GPU从CPU读取数据还是CPU向GPU写入数据?

7
我是并行编程的初学者。我有一个问题,可能看起来很傻,但是当我在谷歌上搜索时没有得到一个明确的答案。
在GPU计算中,有一个设备即GPU和一个主机即CPU。我编写了一个简单的hello world程序,它将在GPU上分配一些内存,将两个参数(比如src []和dest [])传递给内核,将src字符串即Hello world复制到dest字符串,并从GPU获取dest字符串到主机。
字符串“src”由GPU读取还是CPU写入GPU?当我们从GPU获取字符串时,GPU是否向CPU写入或CPU从GPU读取?
在数据传输方面,可能会有四种情况: 1. CPU到GPU - CPU写入GPU - GPU从CPU读取 2. GPU到CPU - GPU写入CPU - CPU从GPU读取
请问有人能解释哪些是可能的,哪些不可能吗?
4个回答

7
在早期的CUDA版本和相应的硬件模型中,GPU更严格地是CPU拥有的协处理器;CPU向GPU写入信息,并在GPU准备好后读取信息。在较低层次上,这意味着真正发生了四件事:CPU将数据写入PCIe,GPU从PCIe读取数据,GPU然后将数据写入PCIe,CPU读取结果。但是,这些交易是由CPU发起的。
最近(CUDA 3?4?也许甚至从2开始?),一些细节被隐藏在应用程序层面之下,以便于GPU代码可以像CPU一样引发传输。考虑统一虚拟寻址,程序员可以访问统一的CPU和GPU内存虚拟地址空间。当GPU请求CPU空间中的内存时,这必须启动从CPU的读取操作。也保留了从CPU端将数据放入GPU的能力。基本上,现在所有的方式都是可能的,在顶部层面(在低层,它基本上是与以往一样的协议:同时从和向PCIe总线读取和写入,但现在,GPU也可以发起交易)。

1
这个过程是通过各种同步控制器最终实现直接内存访问(DMA)的。 - Ani
非常感谢。知道GPU也可以发起事务是很好的。那么,有没有办法通过Opencl中的任何库例程来知道实际上是谁发起了事务?或者使用哪些例程可以强制CPU或GPU执行事务..? - Nike
我对OpenCL的了解还不够深入;话虽如此,如果CUDA没有给你在统一虚拟地址空间中检查变量所在位置的某种方式,我会感到惊讶。这种信息可能很有用,即使在显式管理传输的用例之外(新版本仍应支持)。 - Patrick87

2
实际上,这些都不是问题。您的CPU代码启动数据的复制,但是当数据通过系统上的任何总线由内存控制器传输到GPU的内存时,CPU可以处理其他数据。同样,当GPU完成运行您启动的内核时,您的CPU代码启动数据的复制,但同时GPU和CPU都可以处理其他数据或运行其他代码。
这些副本称为异步或非阻塞副本。您可以选择执行阻塞式副本,在此过程中,CPU等待副本完成。
在启动异步任务时,通常会注册一个“事件”,这是一种标志,您稍后可以检查它,以查看任务是否已完成。

1
在OpenCL中,主机(CPU)独占地控制着GPU和GPU之间所有数据的传输。主机使用缓冲区将数据传输到GPU。主机使用缓冲区从GPU读取(返回)数据。对于某些系统和设备,传输并不是物理上复制字节,因为主机和GPU使用相同的物理内存。这被称为零拷贝。

1
我在这个论坛http://devgurus.amd.com/thread/129897上发现,使用clCreateBuffer中的CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR可以在主机上分配内存,并且不会在设备上复制。
可能会有性能问题,但这正是我要寻找的。请您发表评论。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接