[英]Mixing implicit and explicit CUDA streams
我有一些 CUDA 8.0 代碼(編輯:我繼承的,不是我寫的),基本上看起來像這樣:
cudaMemcpy(devInputData, ..., cudaMemcpyHostToDevice);
kernelThings<<<GRIDS, BLOCKS, 0, myStream>>>(devInputData);
cudaDeviceSynchronize();
cudaMemcpy()
在沒有 stream 的情況下同步工作,所以據我了解,這段代碼是正確的。
如果我使用CUDA_API_PER_THREAD_DEFAULT_STREAM
進行編譯,這段代碼是否仍然安全? 我認為不, cudaMemcpy()
現在異步發生,因此 kernel 有可能在cudaMemcpy()
完成之前啟動。 但是,查看Nsight
分析器,我發現沒有重疊 - 從文字上我看到:
[Memcpy HtoD]
[kernelThings]
兩個函數之間有 16 微秒的間隔。 此行為在應用程序中重復多次。
但是,我接下來刪除cudaDeviceSynchronize()
,重新運行Nsight
,然后看到它們現在重疊了:
[Memcpy HtoD]
[kernelThings]
kernel 現在在cudaMemcpy
完成前 10 微秒啟動。
顯然,正確的解決方法是將 stream 與cudaMemcpyAsync()
一起使用:
cudaMemcpyAsync(devInputData, ..., cudaMemcpyHostToDevice, myStream);
但是,我的問題是為什么我在使用cudaDeviceSynchronize()
時沒有看到進程重疊? 簡單的答案是我可能對不同版本的 CUDA 或 GPU 不那么幸運嗎?
不要依賴隱式/默認流和操作及其同步行為的拐杖。 對於您的第一個“Hello world”級別程序 - 這可能很方便,但正如您自己所注意到的,您必須成為 API 律師或通靈者才能猜測在某些復雜場景中究竟會發生什么。
只需確保您在 kernel 中使用的每個緩沖區都是:
由同一命令隊列上的先前操作填充或
2.2 如果它是 output 緩沖區 - 有一個事件對確保在 output 緩沖區用於其他地方之前執行 kernel
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.