Ошибка памяти в программе CUDA для графического процессора Fermi
Я сталкиваюсь со следующей проблемой на GPU GeForce GTX 580 (Fermi-class).
Просто, чтобы дать вам некоторое представление, я читаю однобайтовые сэмплы, упакованные в файл следующим образом: Реальный (Сигнал 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-класса, к которому у меня есть доступ. Еще одна вещь, которую я заметил, заключается в том, что Ферми не дает ошибок для 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 регистра с двумя закомментированными операторами присваивания.
Я попробовал 32-битный инструментарий вместо 64-битного инструментария, 32-битная компиляция с -m32
опция компилятора, работает без X окон и т. д., но поведение программы такое же.
Я использую драйвер CUDA 4.0 и время выполнения (также пробовал CUDA 3.2) на RHEL 5.6. Вычислительная способность GPU составляет 2,0.
Пожалуйста помоги! Я мог бы опубликовать весь код, если кто-то заинтересован в том, чтобы запустить его на своих картах Fermi.
ОБНОВЛЕНИЕ: Просто для этого, я вставил __syncthreads()
между pf2FFTInX
и pf2FFTInY
операторы присваивания и ошибки памяти исчезли для N
= 32768. Но в N
= 65536, я все еще получаю ошибки. <--
Это длилось недолго. Все еще получаю ошибки.
ОБНОВЛЕНИЕ: Продолжая странное поведение, когда я запускаю программу с использованием cuda-memcheck, я получаю эти 16x16 блоков разноцветных пикселей, случайным образом распределенных по всему экрану. Этого не происходит, если я запускаю программу напрямую.
1 ответ
Проблема была в плохой видеокарте (см. Комментарии). [Я добавляю этот ответ, чтобы удалить вопрос из списка без ответа и сделать его более полезным.]