OpenCL автокорелационно ядро

Написах проста програма, която прави автокорелация, както следва... Използвах директиви за ускоряване на pgi, за да преместя изчислението към графични процесори.

//autocorrelation
void autocorr(float *restrict A, float *restrict C, int N)
{
      int i, j;
      float sum;
      #pragma acc region
      {
        for (i = 0; i < N; i++) {
                        sum = 0.0;
                for (j = 0; j < N; j++) {
                    if ((i+j) < N)
                      sum += A[j] * A[i+j];
                    else
                      continue;
               }
            C[i] = sum;
       }
       }
}

Написах подобна програма в OpenCL, но не получавам правилни резултати. Програмата е следната...Нов съм в програмирането на GPU, така че освен съвети, които биха могли да коригират грешката ми, всякакви други съвети са добре дошли.

__kernel void autocorrel1D(__global double *Vol_IN, __global double *Vol_AUTOCORR, int size)
{

    int j, gid = get_global_id(0);
    double sum = 0.0;

    for (j = 0; j < size; j++) {
            if ((gid+j) < size)
            {
               sum += Vol_IN[j] * Vol_IN[gid+j];
            }
            else
               continue;
               }

    barrier(CLK_GLOBAL_MEM_FENCE);
    Vol_AUTOCORR[gid] = sum;

}

Тъй като съм предал измерението да бъде 1, така че обмислям моето извикване get_global_size(0) да ми даде идентификатора на текущия блок, който се използва за достъп до входния 1d масив.

Благодаря,
Саян


person Sayan    schedule 11.05.2011    source източник
comment
Какви резултати постигате? Ако промените Vol_AUTOCORR[gid] = sum; на Vol_AUTOCORR[gid] = gid;, това дава ли ви очаквания масив от увеличени стойности?   -  person Steve Blackwell    schedule 12.05.2011
comment
Не виждам проблем тук? Какъв е вашият хост код? Правилно ли прехвърляте данните към устройството и обратно?   -  person Rick-Rainer Ludwig    schedule 13.05.2011
comment
Съжалявам за късния отговор...няма проблеми с ядрото, имах грешка в кода на хоста, което доведе до грешни резултати. Благодаря за оценката.   -  person Sayan    schedule 16.05.2011


Отговори (1)


Кодът е правилен. Доколкото знам, това трябва да работи добре и да дава правилни резултати.

бариера(CLK_GLOBAL_MEM_FENCE); не е необходима. Ще получите повече скорост без това изречение.

Проблемът ви трябва да е извън ядрото, проверете дали подавате правилно входа и изваждате правилните данни от GPU.

Между другото, предполагам, че използвате GPU с двойна прецизност, докато правите двойни изчисления. Проверете дали предавате и двойни стойности. Запомнете, че НЕ МОЖЕТЕ да посочите плаващ указател към двойна стойност и обратно. Това ще ви даде грешни резултати.

person DarkZeros    schedule 25.05.2011
comment
Да, забелязах, че БАРИЕРАТА не е необходима в този случай. Благодаря ви, че ме насочихте към типа данни. - person Sayan; 26.05.2011