Ошибка памяти в программе CUDA для графического процессора Fermi - PullRequest
3 голосов
/ 21 июля 2011

Я сталкиваюсь со следующей проблемой на GPU GeForce GTX 580 (класс Fermi).

Просто чтобы дать вам некоторое представление, я читаю однобайтовые сэмплы, упакованные следующим образом в файл:Реальный (Сигнал 1), Воображаемый (Сигнал 1), Реальный (Сигнал 2), Воображаемый (Сигнал 2).(Каждый байт представляет собой знаковый символ, принимающий значения от -128 до 127.) Я считал их в массив char4 и использую приведенное ниже ядро, чтобы скопировать их в два массива float2, соответствующих каждому сигналу.(Это просто изолированная часть более крупной программы.)

Когда я запускаю программу с помощью cuda-memcheck, я получаю либо неквалифицированное unspecified launch failure, либо такое же сообщение вместе с User Stack Overflow or Breakpoint Hit или Invalid __global__ write of size 8 в случайном порядке потоков и индексов блоков.

Основное ядро ​​и связанный с запуском код воспроизводятся ниже. Странно то, что этот код работает (и cuda-memcheck не выдает ошибок) на GPU не-Fermi-класса, к которому у меня есть доступ.Еще одна вещь, которую я заметил, заключается в том, что Fermi не выдает ошибку для N меньше 16384.

#define N   32768

int main(int argc, char *argv[])
{
    char4 *pc4Buf_h = NULL;
    char4 *pc4Buf_d = NULL;
    float2 *pf2InX_d = NULL;
    float2 *pf2InY_d = NULL;
    dim3 dimBCopy(1, 1, 1);
    dim3 dimGCopy(1, 1);
    ...
    /* i do check for errors in the actual code */
    pc4Buf_h = (char4 *) malloc(N * sizeof(char4));
    (void) cudaMalloc((void **) &pc4Buf_d, N * sizeof(char4));
    (void) cudaMalloc((void **) &pf2InX_d, N * sizeof(float2));
    (void) cudaMalloc((void **) &pf2InY_d, N * sizeof(float2));
    ...
    dimBCopy.x = 1024;  /* number of threads in a block, for my GPU */
    dimGCopy.x = N / 1024;
    CopyDataForFFT<<<dimGCopy, dimBCopy>>>(pc4Buf_d,
                                           pf2InX_d,
                                           pf2InY_d);
    ...
}

__global__ void CopyDataForFFT(char4 *pc4Data,
                               float2 *pf2FFTInX,
                               float2 *pf2FFTInY)
{
    int i = (blockIdx.x * blockDim.x) + threadIdx.x;

    pf2FFTInX[i].x = (float) pc4Data[i].x;
    pf2FFTInX[i].y = (float) pc4Data[i].y;
    pf2FFTInY[i].x = (float) pc4Data[i].z;
    pf2FFTInY[i].y = (float) pc4Data[i].w;

    return;
}

Еще одна вещь, которую я заметил в своей программе, это то, что если я закомментирую что-либов моем ядре нет двух операторов присваивания char-to-float, ошибки памяти нет. Еще одна вещь, которую я заметил в своей программе, это то, что если я закомментирую либо первые два, либо последние два оператора присваивания char-to-float вмое ядро, нет ошибки памяти.Если я закомментирую одну из первых двух (pf2FFTInX), а другую - из вторых двух (pf2FFTInY), ошибки по-прежнему возникают, но менее часто.Ядро использует 6 регистров со всеми четырьмя операторами присваивания без комментариев и использует 5 4 регистров с двумя закомментированными операторами присваивания.

Вместо 64-битного я попробовал 32-битный инструментарийинструментарий, 32-битная компиляция с опцией компилятора -m32, работа без X windows и т. д., но поведение программы такое же.

Я использую драйвер CUDA 4.0 и среду выполнения (также пробовал CUDA 3.2) на RHEL5.6.Вычислительная способность GPU составляет 2,0.

Пожалуйста, помогите!Я мог бы опубликовать весь код, если кто-то заинтересован в том, чтобы запустить его на своих картах Fermi.

ОБНОВЛЕНИЕ: Просто ради этого я вставил __syncthreads() между pf2FFTInX и pf2FFTInY операторов присваивания и ошибки памяти исчезли для N = 32768. Но при N = 65536 я все еще получаю ошибки. <-- Это продолжалось недолго.По-прежнему получаются ошибки.

ОБНОВЛЕНИЕ: Продолжая странное поведение, когда я запускаю программу с использованием cuda-memcheck, я получаю эти разноцветные пиксели 16x16 блоков, случайно распределенных по всему экрану.Этого не происходит, если я запускаю программу напрямую.

1 Ответ

2 голосов
/ 20 февраля 2012

Проблема была в плохой видеокарте (см. Комментарии). [Я добавляю этот ответ, чтобы удалить вопрос из списка без ответа и сделать его более полезным.]

...