簡體   English   中英

混合隱式和顯式 CUDA 流

[英]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 中使用的每個緩沖區都是:

  1. 由同一命令隊列上的先前操作填充或


  2. 2.1 如果它是一個輸入緩沖區 - 有一個事件對確保在 kernel 在另一個 stream 上啟動之前發生任何影響緩沖區的事情,並且

    2.2 如果它是 output 緩沖區 - 有一個事件對確保在 output 緩沖區用於其他地方之前執行 kernel

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM