CUDA Time Events - PullRequest
       9

CUDA Time Events

1 голос
/ 14 декабря 2011

Я рассчитываю, сколько времени понадобится моей программе CUDA для вычисления матриц определенного размера.Например, 10x10, 100x100, 500x500, 100x1000.

Однако результаты совсем не те, что я ожидал.Числа на графике не соответствуют ожидаемым.С увеличением размера матриц время вычислений уменьшается.

Например, вот среднее время (из 1000 прогонов): 10x10: 0.032768s 100x100: 0.068960s 500x500: 0.006336s 1000x1000: 0.018400s

Время уменьшается, затем снова увеличиваетсяна 1000. Что происходит?Разве цифры не должны достигать пика в определенной точке?Почему это происходит на американских горках, как это?

Вот как выполняется фактический тайминг-код:

int blocksNeeded=0;
cudaError_t cudaStatus;
blocksNeeded=(size/MAXTHREADS)+1;
int threadsPerBlock = MAXTHREADS/blocksNeeded+1;
cudaEvent_t start, stop;
float elapsedtime;
.
.
.
.
.
cudaEventCreate(&start);
cudaEventCreate(&stop); 
cudaEventRecord(start, 0);
addKernel<<<blocksNeeded, size>>>(dev_c, dev_a, dev_b,size);
cudaStatus = cudaDeviceSynchronize();
cudaEventRecord(stop, 0); 
cudaEventSynchronize(stop); 
cudaEventElapsedTime(&elapsedtime, start, stop);
cudaEventDestroy(start);
cudaEventDestroy(stop);

, где MAXTHREADS - 1024, а size - количество элементов Iиметь в матрице.Матрица IE 10x10 будет иметь 100 элементов, что по размеру.

Обновлено с ядром:

__global__ void addKernel(float *c, float *a, float *b,int size)
{
    int idx = blockDim.x * blockIdx.x + threadIdx.x;
    if(idx < size) 
        c[idx] = a[idx] + b[idx];

}

Ответы [ 2 ]

4 голосов
/ 15 декабря 2011

Я провел тест на недавнем кластере графических процессоров, оснащенном NVIDIA Tesla M2090.В основном я выполняю сложение векторов с разными размерами.Результаты:

Size     Kernel time (msec)
===========================
2        0.04
4        0.010912
8        0.012128
16       0.012256
32       0.011296
64       0.01248
128      0.012192
256      0.012576
512      0.012416
1024     0.012736
2048     0.01232
4096     0.011968
8192     0.011264
16384    0.007296
32768    0.007776
65536    0.009728
131072   0.018304
262144   0.031392
524288   0.055168
1048576  0.10352

То, что вы видите, это то, что колено имеет размер вектора 16384, что в основном напоминает ваши наблюдения.Это не ошибка, а нормальное поведение, поскольку графический процессор должен использоваться для отображения производительности.Точка использования, в случае Tesla M2090, достигла примерно 16384 параллельных добавлений.

То, как вы измеряете производительность ядра, совершенно нормально.Я предполагаю, что вы взяли это из «Руководства по передовому опыту» для CUDA.

Примечание: Обратите внимание, что показанные данные генерируются с использованием одного ядра.запустить, т.е. это не репрезентативно.Обычно для измерения точного времени ядро ​​должно запускаться несколько раз с одной и той же проблемой, а время ядра является средним значением прогонов.

0 голосов
/ 14 декабря 2011

Вы должны вызвать ядро ​​с

addKernel<<<blocksNeeded, MAXTHREADS>>>(dev_c, dev_a, dev_b,size);

Второй параметр в вызове ядра - это количество потоков, запускаемых в каждом блоке, а не общее количество потоков.

При 100x100 вы уже превышаете максимальное количество потоков в блоке, которое составляет 1536 для вычислительных возможностей 2.x

И только что заметил, что вы вычисляете какие-то нитиPerBlock, что неправильно, и что вы им не пользуетесь. Выберите количество потоков в блоке. Затем разделите на общее количество элементов для обработки и добавьте к нему 1, если остаток отличается от 0, и вы получите количество блоков для запуска.

...