之前寫的CUDA程序,想測量一下性能,網上很多用的是CPU端計時,很不准確。翻了一下書,發現這里應該使用事件來計時。
CUDA中的事件本質上是一個GPU時間戳,這個時間戳是在用戶指定的時間點上記錄的。由於GPU本身支持記錄時間戳,因此就避免了當使用CPU定時器來統計GPU執行的時間時可能遇到的諸多問題。
首先創建兩個事件,起始時間和結束時間:
cudaEvent_t start, stop; cudaEventCreate(&start); cudaEventCreate(&stop);
然后記錄起始時間:
cudaEventRecord(start, 0);
然后執行GPU端代碼,執行完畢記錄結束時間:
cudaEventRecord(stop, 0);
由於核函數被調用后,GPU執行完之前,CPU會繼續執行程序中的下一行代碼,因此此時記錄的時間不准確,應該把這條語句放入GPU的未完成工作隊列中,使得直到GPU執行完了的調用cudaEventRecord()之前的所有語句時,事件才會被記錄下來。修復這個問題只需要在下面加一行代碼:
cudaEventSynchronize(stop);
記錄完畢后,計算總耗時:
float elapsedTime; cudaEventElapsedTime(&elapsedTime, start, stop);
這里得到的elapsedTime就是執行GPU端代碼所需時間,單位ms。
總流程為:
cudaEvent_t start, stop; cudaEventCreate(&start); cudaEventCreate(&stop); cudaEventRecord(start, 0); // 在GPU上執行一些工作 cudaEventRecord(stop, 0); cudaEventSynchronize(stop); float elapsedTime; cudaEventElapsedTime(&elapsedTime, start, stop);
注意:
由於CUDA事件時直接在GPU上實現的,因此它們不適用於對同時包含設備代碼和主機代碼的混合代碼計時,也就是說,如果你試圖通過CUDA事件對核函數和設備內存復制之外的代碼進行計時,將得到不可靠的結果。