首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对于P2P拷贝,cudaMemcpy()和cudaMemcpyPeer()有什么区别?

对于P2P拷贝,cudaMemcpy()和cudaMemcpyPeer()有什么区别?
EN

Stack Overflow用户
提问于 2014-03-27 17:08:46
回答 1查看 7.7K关注 0票数 4

我想复制数据从GPU0-DDR到GPU1-DDR直接没有CPU-RAM。

正如页面-15:Programming.pdf中所说的

代码语言:javascript
复制
Peer-to-Peer Memcpy
 Direct copy from pointer on GPU A to pointer on GPU B

 With UVA, just use cudaMemcpy(…, cudaMemcpyDefault)
     Or cudaMemcpyAsync(…, cudaMemcpyDefault)

 Also non-UVA explicit P2P copies:
     cudaError_t cudaMemcpyPeer( void * dst, int dstDevice, const void* src, 
        int srcDevice, size_t count )
     cudaError_t cudaMemcpyPeerAsync( void * dst, int dstDevice,
        const void* src, int srcDevice, size_t count, cuda_stream_t stream = 0 )
  1. 如果我使用cudaMemcpy(),那么首先必须设置cudaSetDeviceFlags( cudaDeviceMapHost )标志吗?
  2. 是否必须使用从函数cudaMemcpy()获得的cudaHostGetDevicePointer(& uva_ptr, ptr, 0)指针?
  3. 函数cudaMemcpyPeer()是否有任何优点,如果没有任何优势,为什么需要它?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-03-27 21:48:43

统一虚拟寻址(UVA)为所有CPU和GPU存储器提供一个地址空间,因为它允许从指针值确定物理内存位置。

点对点备忘录与UVA*

当UVA成为可能时,cudaMemcpy就可以用于对等memcpy,因为数据自动化系统可以推断哪个设备“拥有”哪个内存。使用UVA执行点对点memcpy通常需要的说明如下:

代码语言:javascript
复制
//Check for peer access between participating GPUs: 
cudaDeviceCanAccessPeer(&can_access_peer_0_1, gpuid_0, gpuid_1);
cudaDeviceCanAccessPeer(&can_access_peer_1_0, gpuid_1, gpuid_0);

//Enable peer access between participating GPUs:
cudaSetDevice(gpuid_0);
cudaDeviceEnablePeerAccess(gpuid_1, 0);
cudaSetDevice(gpuid_1);
cudaDeviceEnablePeerAccess(gpuid_0, 0);

//UVA memory copy:
cudaMemcpy(gpu0_buf, gpu1_buf, buf_size, cudaMemcpyDefault);

没有UVA的点对点备忘录

当UVA是不可能的,那么点对点备忘录是通过cudaMemcpyPeer完成的。下面是一个例子

代码语言:javascript
复制
// 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); 
// Set device 1 as current
cudaSetDevice(1); 
// Copy p0 to p1
cudaMemcpyPeer(p1, 1, p0, 0, size); 
// Launch kernel on device 1
MyKernel<<<1000, 128>>>(p1);

如您所见,虽然在前一种情况下(可能的UVA),您不需要指定不同的指针所引用的设备,而在后一种情况下(UVA不可能),您必须显式地提到指针所引用的设备。

指令

代码语言:javascript
复制
cudaSetDeviceFlags(cudaDeviceMapHost);

用于启用主机到设备内存的映射,这是另一回事,并且考虑主机<->设备内存移动,而不是对等内存移动,这是您的文章的主题。

最后,你的问题的答案是:

  1. 否;
  2. 否;
  3. 在可能的情况下,启用UVA并使用cudaMemcpy (不需要指定设备);否则,使用cudaMemcpyPeer (并且需要指定设备)。
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22694518

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档