2011-12-14 46 views
1

我時間需要多長時間我的CUDA程序來計算具有一定規模的矩陣。例如,10x10,100x100,500x500,100x1000。CUDA時間事件

然而,結果完全不是我所期待的。圖表的數字不符合預期。隨着矩陣大小的增加,計算時間減少。

例如,這裏是平均時間(從1000次運行):10×10 :0.032768s 100x100的:0.068960s 500×500:0.006336s 1000×1000: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,並且尺寸是我在矩陣中的元素的量。 I.E. 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

你如何計算blocksNews和size? –

+0

你嘗試過沒有cudaDeviceSynchronize嗎?這不是必需的時間,它可能會影響結果(即使不是你描述的方式)。和其他評論+1。 – jmsu

回答

3

我做了搭載NVIDIA的Tesla M2090最近的GPU集羣上的測試。基本上我正在執行不同大小的矢量添加。結果是:

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具有要用於顯示的性能。在特斯拉M2090的情況下,利用率達到約16384個並行增量。

你測量內核性能的方法是完全可行。我假設你已經從CUDA的「最佳實踐指南」中獲得了這一點。

說明:請考慮,所示的數據是通過使用單個內核運行,我生成。即它不具有代表性。一般來說,對於精確的時間測量,內核應該運行多次,而且內核時間是運行的平均值。

+0

+ +1對於沒有魔術字的好回答 –

+0

+1用於提供數據,但...測量結果很好,但仍不能解釋爲什麼會發生這種情況。爲什麼尺寸2大於4?不包括2,對於所有其他有效值,預計時間峯值爲1024。在2048年,第一個壞內核參數的時間開始減少,但爲什麼它們不是恆定的?內核不會失敗嗎? – jmsu

+0

感謝您提供數據,我很感激。我遇到了問題,如果我運行超過2000個seg故障,但我正在嘗試解決這個問題。當你說16384平行增加時,特斯拉擁有的最大線程數是多少? – Dan

0

您必須調用與

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

在內核調用的第二個參數內核中每個塊啓動線程的數量,而不是總人數線程。

在100x100的你已經超過它在計算能力2.x的

是1536每個塊的線程的最大數量,並只注意到你計算某種threadsPerBlock的這是錯誤的,你不使用它。每塊選擇多個線程。然後除以要處理的元素的總數,如果餘數不等於0,則加1,並得到要啓動的塊的數量。

+0

但這並不能解釋爲什麼他的措施在500x500和1000x1000下更低。或者我錯過了什麼? –

+0

它解釋了因爲內核無法啓動,無效的參數錯誤或類似的東西。我不明白他們爲什麼100x100也不低,但有錯誤,你不能指望可靠的結果。 – jmsu

+0

我同意,但他聲明所有的內核都執行沒有錯誤 –