我应该使用什么设备号(0或1)来复制P2P(GPU0-> GPU1)?

时间:2014-03-29 20:00:24

标签: cuda gpgpu nvidia

cudaSetDevice();中设置0或1,使用cudaStreamCreate(stream); cudaMemcpyPeerAsync(p1, 1, p0, 0, size, stream);复制P2P(GPU0-> GPU1)需要多少设备?

代码:

// Set device 0 as current
cudaSetDevice(0); 
float* p0;
size_t size = 1024 * sizeof(float);
// Allocate memory on device 0
cudaMalloc(&p0, size); 
// Set device 1 as current
cudaSetDevice(1); 
float* p1;
// Allocate memory on device 1
cudaMalloc(&p1, size); 
// Set device 0 as current
cudaSetDevice(0);
// Launch kernel on device 0
MyKernel<<<1000, 128>>>(p0); 

// What number do I must to set 0 or 1?
cudaSetDevice(1); // cudaSetDevice(0); 
cudaStream_t stream;
cudaStreamCreate(stream);

// Copy p0 to p1
cudaMemcpyPeerAsync(p1, 1, p0, 0, size, stream); 
cudaStreamSynchronize(stream);

// Launch kernel on device 1
cudaSetDevice(1); 
MyKernel<<<1000, 128>>>(p1);

更新日期:2014年3月31日: 或者当前上下文仅对__global__ kernel_function()重要,而不是cudaMemcpyPeerAsync()?对于cudaMemcpyAsync()cudaMemcpyPeerAsync()来说,只有从(源指针)为设备创建流的数据被复制时才重要,不是吗?

1 个答案:

答案 0 :(得分:3)

在对cudaMemcpyPeerAsync的调用中,您可以指定非默认stream。因此,您的第一个问题是:我应该在调用cudaSetDevice之前通过cudaMemcpyPeerAsync设置哪个设备?

答案是您必须按cudaSetDevice设置已为其创建stream的设备。您可以使用为源设置的stream或目标设备。虽然据我所知,documentation中没有明确提到,但这种可能性可以通过Robert Crovella对How to define destination device stream in cudaMemcpyPeerAsync()?的回答来推断。请注意,截至2011年,根据Multi-GPU Programming,当stream属于源GPU时,性能最大化。

让我回想一下在多GPU框架中使用streams时的一些重要观点,借用Multi-GPU Programming并支持上述陈述:

  1. CUDA streams 每台设备;
  2. streams由创建时当前的GPU确定;
  3. 只有当设备是最新的时,才能发出对stream的呼叫。