2011-12-14 2 views
1

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

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

Например, здесь среднее время (от 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 и размер количество элементов я в матрице. И.Е. Матрица 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

Вы проверяете коды возврата из выполнения ядра? Может быть, на 500 ядро ​​не удалось запустить – flipchart

+1

Как вы вычисляете blocksNeeded и размер? –

+0

Вы пробовали без cudaDeviceSynchronize? Это не требуется для синхронизации, и это может повлиять на результаты (даже если это не так, как вы описали). И +1 к другим комментариям. – jmsu

ответ

3

Я провел тест на недавнем кластере GPU, оснащенном 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.
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, который в основном напоминает свои наблюдения. Это не ошибка, но нормальное поведение, так как GPU должен использоваться для показа производительности. Точка использования, в случае Tesla M2090, достигла около 16384 параллельных дополнений.

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

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

+0

+1 для хорошего ответа без слова magic –

+0

+1 для предоставления данных, но ... измерение отличное, но до сих пор не объясняет, почему это происходит. Почему размер 2 больше 4? Исключая 2, для всех других допустимых значений ожидается пик времени размером 1024. В 2048 году первый параметр плохого ядра времена начинают уменьшаться, но почему они не являются постоянными? Разве ядро ​​не терпит неудачу? – jmsu

+0

Спасибо за предоставление данных, я ценю это. Я столкнулся с проблемами, когда, если я запускаю более 2000, это seg faults, но я в настоящее время пытаюсь это исправить. Когда вы говорите 16384 параллельных дополнений, является ли максимальное количество потоков, которые имеет Тесла? – Dan

0

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

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

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

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

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

+0

Но это не объясняет, почему его меры ниже для 500x500 и 1000x1000. Или я что-то пропустил? –

+0

Это объясняется тем, что ядро ​​не запускается, ошибка недопустимых параметров или что-то в этом роде. Я не вижу, почему они не ниже для 100x100, но с ошибками вы не можете ожидать надежных результатов. – jmsu

+0

Согласен, но он утверждает, что все ядра выполняются без ошибок –

Смежные вопросы