是的,您可以使用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