是的,您可以使用CUDA streams在這種情況下管理訂單和相關性。
我們假設您將要覆蓋複製和計算操作。這通常意味着您會將輸入數據分解爲「塊」,並且您會將塊複製到設備,然後啓動計算操作。每個內核啓動都在一個「大塊」數據上運行。
我們可以在主機代碼的循環管理過程:
// create streams and ping-pong pointer
cudaStream_t stream1, stream2, *st_ptr;
cudaStreamCreate(&stream1); cudaStreamCreate(&stream2);
// assume D is already on device as dev_D
for (int chunkid = 0; chunkid < max; chunkid++){
//ping-pong streams
st_ptr = (chunkid % 2)?(&stream1):(&stream2);
size_t offset = chunkid*chunk_size;
//copy A and B chunks
cudaMemcpyAsync(dev_A+offset, A+offset, chksize*sizeof(A_type), cudaMemcpyHostToDevice, *st_ptr);
cudaMemcpyAsync(dev_B+offset, B+offset, chksize*sizeof(B_type), cudaMemcpyHostToDevice, *st_ptr);
// then compute C based on A and B
compute_C_kernel<<<...,*st_ptr>>>(dev_C+offset, dev_A+offset, dev_B+offset, chksize);
// then compute Result based on C and D
compute_Result_kernel<<<...,*st_ptr>>>(dev_C+offset, dev_D, chksize);
// could copy a chunk of Result back to host here with cudaMemcpyAsync on same stream
}
頒發給同一個流的所有操作都保證,以便在設備上執行(即順序)。發佈給單獨流的操作可能會重疊。因此,上述序列應:
- 拷貝A的組塊到設備
- B的塊複製到設備
- 發射內核來計算C來自A和B
- 發射一個內核以計算來自C和D的結果
上述步驟將針對每個塊重複進行,但是會對替代流發出連續的塊操作。因此,塊2的複製操作可以與塊1的內核操作重疊等。
您可以通過查看CUDA流上的演示文稿來了解更多信息。 Here就是一個例子。
較新的設備(開普勒和麥克斯韋)應該相當靈活地瞭解設備上操作重疊所需的程序問題順序。較老的(費米)設備可能對發佈訂單敏感。你可以閱讀更多關於here