2017-04-14 63 views
0

我试图用memcpyasync D2H重叠内核执行,但它不起作用。我有N组元素。每组有64个元素可以并行处理。由于数据依赖性,组的处理必须是连续的。也就是说,组i的元素必须在处理组i-1的元素之后进行处理。处理组中的每个元素都会产生一个必须从GPU传输到CPU的输出。为了重叠这个D2H数据传输,我将一个组的元素划分为多个块,以便可以使用这些流重叠给定块上的内核执行和D2H MemcpyAsync。我使用下面的伪代码来处理使用K流的N组元素。CUDA流并发和D2H数据传输重叠

groupId=0; 
`while(groupId< N){` 

    for(i=0;i<K;++i) 

// all stream must wait to complete the kernel execution 
of last stream before starting of the processing of next group 

if(groupId!=0) 

cudaStreamWaitEvent(stream[K-1],syncEvent,0) 
kernelA<<< >>>(----,----,----); 
CUDAEventRecord(syncEvent,stream[K-1]); 
cudaMemcpyAsync(,,,cudaMemcpyDeviceToHost,stream[i]); 
} 

groupId++ 

} 

当我使用两个流然后有一些重叠,同时,当我增加流的数量存在,如以下图1所示没有重叠。 Processing of 64 elements using two stream.

Processing of 64 elements using four stream

请解释为什么D2H数据传输不完全重叠。此外,在四个流的情况下,每个流的内核被调用16个线程块,每个线程块的大小为128个线程。从概念上讲,应该同时执行两个流(每个都在SM上),因为GPU上有足够的资源可用。但是,不同流的内核执行没有并发(图2)。这种情况下没有并发的原因是什么?

回答

1

你的64个字节传输是太短与任何重叠 - 在满的PCIe 2.0的速度(约6GB/s)的实际传输需要大约10 纳米秒。在截图的比例尺上,这将大约是探查器时间轴上像素宽度的1/1000。条和间隙的有限宽度完全是由于每次传输的开销(建立等)。

您希望传输兆字节的顺序以便能够与计算重叠传输。