2014-02-26 75 views
0

我正在分析花費在內核上的總時間,運行多個時間,並想知道這段代碼是否會給我流內核上的總花費,或者如果返回的時間需要乘以啓動次數。測量使用流時內核花費的總時間

cudaEvent_t start, stop;  
cudaEventCreate(&start); 
cudaEventCreate(&stop); 


for(x=0; x<SIZE; x+=N*2){ 

    gpuErrchk(cudaMemcpyAsync(data_d0, data_h+x, N*sizeof(char), cudaMemcpyHostToDevice, stream0)); 
    gpuErrchk(cudaMemcpyAsync(data_d1, data_h+x+N, N*sizeof(char), cudaMemcpyHostToDevice, stream1)); 


    gpuErrchk(cudaMemcpyAsync(array_d0, array_h, wrap->size*sizeof(node_r), cudaMemcpyHostToDevice, stream0)); 
    gpuErrchk(cudaMemcpyAsync(array_d1, array_h, wrap->size*sizeof(node_r), cudaMemcpyHostToDevice, stream1)); 

    cudaEventRecord(start, 0); 
     GPU<<<N/512,512,0,stream0>>>(array_d0, data_d0, out_d0); 
     GPU<<<N/512,512,0,stream1>>>(array_d1, data_d1, out_d1); 
    cudaEventRecord(stop, 0); 

    gpuErrchk(cudaMemcpyAsync(out_h+x, out_d0 , N * sizeof(int), cudaMemcpyDeviceToHost, stream0)); 
    gpuErrchk(cudaMemcpyAsync(out_h+x+N, out_d1 ,N * sizeof(int), cudaMemcpyDeviceToHost, stream1)); 

} 

float elapsedTime; 
cudaEventElapsedTime(&elapsedTime, start, stop); 
cudaEventDestroy(start); 
cudaEventDestroy(stop); 
printf("Time %f ms\n", elapsedTime); 

回答

0

它不會捕獲所有內核循環執行時間。

documentation

如果cudaEventRecord()以前被稱爲事件,那麼這個調用將在活動覆蓋任何現有狀態。任何後續調用檢查事件狀態的調用都只會檢查最近一次對cudaEventRecord()的調用的完成情況。

如果您認爲每次通過循環的執行時間大致相同,那麼您可以將結果乘以通過次數。

請注意,您應該發出的stop事件cudaEventSynchronize()呼叫,該呼叫之前cudaEventElapsedTime()

0

基於事件的時機加入CUDA,使芯片上執行細粒度的時間(例如,你即使只有一個內核調用被事件啓動/停止調用括起來,也應該獲得準確的時間)。但是流和亂序執行引入了cudaEventRecord()記錄的「時間戳」含義的模糊性。 cudaEventRecord()接受一個流參數,並據我所知它尊重那個流參數;但是流的執行可能受到其他流的影響,例如,如果他們爭奪一些資源。

因此,最好的做法是在NULL流上調用cudaEventRecord()進行序列化。有趣的是,英特爾與RDTSC有着相似的歷史,他們在同一產品中引入了超標量執行和時間戳記錄。 (對於NVIDIA,它是CUDA 1.1;對於英特爾,它是奔騰)。同樣,英特爾不得不修改他們對那些依賴RDTSC作爲序列化指令的開發者的指導,告訴他們明確序列化以獲得有意義的時序結果。

Why isn't RDTSC a serializing instruction?