Gpu可以和Cpu进行共享吗?

如果可以的话,是不是很好的提高计算机运行效率?

推荐  (1) | 27人关注关注
12个答案
65 2

LePtC物理学博士生

2014-05-18 18:45

哎,这就是我正在做的毕设课题丫,用GPU并行计算加速模拟程序 ...

GPU 是特别为计算密集,高并行度计算(如图像渲染)设计的,将更多晶体管用于数据处理,没有 CPU 那么多的缓存和流控。因此 CPU 擅长逻辑复杂的计算,但发动一个线程的开销较大。GPU 虽然逻辑比较简单,但单个线程的开销小,在同样的资源下可以发动更多的线程。

2006 年 11 月,英伟达(NVIDIA)推出了 CUDA,一种基于新的并行编程模型和指令集架构的通用计算架构。
CUDA 的编程模型如下图左图,GPU 的工作由主机(host)系统来调度,此处主机就是指 CPU 啦。一个主机系统可以安装多个 GPU,每个 GPU 都是一个独立的设备(device),与主处理器异步运转。并行计算的任务叫做内核(kernel),它的计算将通过 CPU 在 GPU 上发动大量的线程(thread)来完成。

CPU 和 GPU 之间的数据交换可以通过 cudaMemcpy 命令来进行,数据将通过 PCIe 总线在内存和显存间传输。CUDA 4.0 以上提供了统一虚拟地址空间(UnifiedVirtual Address Space),所以现在也可以通过分页锁定的主机存储器(Page-Locked Host Memory)来隐式地完成数据传输。最新的 Maxwell 架构的显卡甚至实现了统一虚拟内存(Unified Virtual Memory),可以直接把内存和显存当成一个存储器来编程了。

计算能力 2.0 以上的 NVIDIA 显卡可以指定程序按双精度浮点来计算,所以精度不是问题,双精度比单精度算得慢一些。

我们的组里有一个用蒙特卡洛方法模拟偏振光子散射的程序,一般需要模拟几千万个光子才能达到足够的分辨率,用 CPU 程序模拟的话需要几个小时,老板让我把程序改成 GPU 的。一个月后,我在我 2010 年的笔记本电脑上实现了 GPU版本的程序,五千万个光子模拟四组只需五分钟,加速倍数在 60 倍左右。我很 happy 地把毕业论文交上去了,老板看过之后十分满意,我窃以为毕设就此撸完啦。

。。。。。。

老板看过之后十分满意,然后说你再撸一篇英文的,拿出去发 ...

#我到底是做理论物理的还是计算物理的#...

24 0

我觉得@LePtC 的回答更侧重CPU和GPU在计算上的不同,而对楼主的问题"如何共享"谈得不够深入。因此想对他描述如下内容做进一步补充,欢迎交流:

CPU 和 GPU 之间的数据交换可以通过 cudaMemcpy 命令来进行,数据将通过 PCIe 总线在内存和显存间传输。CUDA 4.0 以上提供了统一虚拟地址空间(UnifiedVirtual Address Space),所以现在也可以通过分页锁定的主机存储器(Page-Locked Host Memory)来隐式地完成数据传输。最新的 Maxwell 架构的显卡甚至实现了统一虚拟内存(Unified Virtual Memory),可以直接把内存和显存当成一个存储器来编程了。


先铺垫一些基本概念。
内存控制器:
CPU和GPU都需要借助内存控制器才能对内存/显存进行访问,可能二者有各自独立的内存控制器,也可能共享,根据具体配置有所不同。

内存和显存:
本质都是memory,只是协议、速度的不同。你看到的主板配DDRX的内存,显卡配GDDRX的内存主要是出于性能和成本的综合考虑来决定的。比如Sony最新的PS4就全面使用了GDDR5作为系统内存和显存,而Xbox One采用了DDR3作为系统内存和显存。其实除了这两种常规的memory,还有其他的memory被显卡使用。Intel从IvyBridge系列开始,CPU/GPU内部使用了一块L3 cache来做图形渲染加速使用;AMD早起的集成显卡也有一块额外的memory单独给图形渲染使用;Xbox One也有一块32Mb的ESRAM来加速图形渲染。有点概念的人应该知道SRAM的速度是很快的,但成本也较DRAM高很多,所以零售产品不可能大量使用。一个题外话,虽然DDR3比GDDR5慢很多,但Xbox One在渲染上并不输给PS4很多,就是ESRAM这块小东西起的作用。
总结来说,系统内存,显存,附加内存都可以作为GPU渲染的临时存贮空间。

集成显卡和独立显卡:
除去字面上集成还是独立的区别,考虑到我们要讨论的主题,集成和独立显卡对"显存"的访问是主要区别。集成显卡以固化在主板或直接集成在CPU中的方式出现,虽没有物理插槽,但仍会被系统识别为一个标准的PCI设备。

大部分集成显卡都是借用一部分系统内存来作为自己的显存的,而借用的方式主要有两种:一种是BIOS或者系统内核直接保留一部分作为显存,这部分不会被计入到OS能看到的系统内存总和之内,通常我们会称之为dedicated video memory;一种是显卡驱动动态向OS申请分配,我们称之为dedicated system memory,这部分会被计入系统内存总和。而上面提到L3 cache,或者ESRAM,都是只有显卡和显卡驱动自己知道的,为简化情况这里我暂且不讨论。

对于独立显卡,几乎都会有自己的显存,我们称之为dedicated video memory,从软件的角度来说,和BIOS为集成显卡保留系统内存作为显存的性质没有区别。

不管集成显卡还是独立显卡,仅有专用memory是不够的,所以还有一种类型的memory,是显卡通过页表映射来访问系统内存的,这种页表被称作GART表(Graphics Address Remapping Table),这种类型的memory叫做shared system memory。
比如我有两个游戏在跑,当我切换到其中一个时,发现需要的显存数量不够了(dedicated比shared访问更快,尤其是对于独立显卡来说),此时OS可以把暂时不渲染的那个游戏的相关的环境和渲染中间过程从dedicated复制到shared,这个过程叫做paging,把更高速的显存给活动的游戏使用,而后台游戏完全不活动时,OS甚至可以将shared里的内容进一步paging到硬盘文件上。
或者对于某些3D应用程序,有CPU绘制的部分,也有GPU渲染的部分,我可以根据需要,分配不同类型的内存资源,有的用dedicated,有些用shared,这样可以更灵活的选择合适的内存使用。


铺垫了这么多,该来说一说CPU和GPU怎么互相访问对方的资源。
@LePtC 提到了地址空间。其实互访的本质不是地址空间,统一的地址空间只是为上层程序开发者提供了更大的便利而已,试想你要写一个OpenCL或者CUDA的程序,两边的变量复制来复制去,还要考虑CPU和GPU地址的转化,是多么麻烦的事情。所以统一地址空间的形式背后,就有必要了解CPU,GPU怎么访问对方资源。

对集成显卡来说,因为本质上都是系统内存,都有CPU认识的物理地址,因此理论上CPU都能完全访问。但实际并非如此。如果是被保留的那种形式,OS并不知道这部分内存的存在,所以按照安全的办法是不能访问这部分内容的。怎么办呢?前面说过,显卡仍然作为一个PCI设备而存在,PCI设备有自己的PCI配置空间,其中的BAR寄存器的值能够让OS知道,去哪个地址能访问到显存(被保留的系统内存),以及能访问多大范围。也就是通过MMIO的方式了。之所以32位操作系统即时插了4G内存也认不全,除了BIOS保留用,就是很多PCI设备的MMIO占用了本应分配给物理内存的地址空间。如果是dedicated system memory,因为是通过OS的API申请的,位于OS能够访问到的内存范围内,所以CPU都能访问到所有的显存。

对独立显卡来说,显存位于卡上,也和标准PCI设备一样,CPU通过BAR寄存器来知道去什么物理地址能够访问到显存。

当CPU通过MMIO访问显存时,会把请求发到总线,显卡自己的内存控制器根据请求重新计算出所请求的地址在显存内的偏移,如此就可以访问。需要注意的是,对于MMIO的访问方式,由于PCI标准的限制,CPU是不能够访问到全部的显存的,因此各家厂商都有自己方法,打个比方,就是开一个可移动的"窗口",使得CPU能通过这个移动窗口访问全部显存。但这样的访问需要驱动的参与,并且同样地址所对应的实际显存位置不是固定的。

对于shared system memory,CPU自然是可以访问的。

GPU访问CPU资源相对简单,GPU的内存控制器告诉总线一个地址,系统总线会将请求解析并发到内存控制器,如此。

对于shared system memory,显卡会根据设置好的页表,来进行地址转换,也就是说告诉显卡的一个地址,经过GART表的转换,会对应到一个物理内存里的物理地址。于是GPU就能够通过自己认识的地址来访问系统内存了。

以上只是物理上的通路,实际实现中还要涉及到操作系统和驱动的实现,比如windows和linux上都有各自的显存管理机制和内存管理机制,显卡驱动也会做相应的管理,并不是说有一个地址就可以随意访问的。在实际的应用中,利用GPU并行计算出现之前,如果一块内容即需要CPU处理也要GPU处理,通常的做法是copy来copy去。这种copy可以通过显卡的DMA机制来进行,当然也可以用OS API memcpy来实现。这是这种来回的copy严重限制的协同计算的效率。

最后回到主题,要想CPU/GPU协同计算,能不能互访并不是瓶颈,瓶颈在于访问的效率问题。只有统一的虚拟地址空间,只是软件上带来了编程的便利,并未在硬件层面解决来回copy和访问效率低下的问题。对于独立显卡来说,除了提高总线的效率,使得CPU/GPU能更快、更大范围的互访之外,SDK软件层更有效合理的选择使用系统内存还是显存非常重要。对于集成显卡来说,需要在硬件层面有一个统一的地址转换的内存控制器,这样CPU/GPU可以使用同样的页表,在同样地址空间操作同样的内存,达到访问效率的最优。这样的地址空间已不仅仅是软件看到的虚拟地址空间,而是在物理地址空间上也做到了统一。

不考虑商业推广因素,以上各种相关技术都在发展之中。但其实目前CPU/GPU并行计算的一个主要问题是,很难根据各种不同情况动态调整CPU,GPU的负载,很多优化还是case by case的来看,软件的,硬件的。当目的已经不是做一个能用的,而是如何做一个最优的时候,通用性不强就是短板,因此对编程要求还是较高的,而且还得具体问题具体分析。

以上,欢迎交流。

(修改原因: 错别字)

20 0

可以。
不然你以为3D游戏们在干啥?
至于提升效率,GPU的并行计算结构需要进行额外指定编程结构,即专门为了GPU进行编程,有所谓CUDA C编程也~

10 0

且不说单核能力,CPU才有几个几十个核,而GPU则有数百上千的流处理器,所以面对琐碎的运算GPU强,但是面对基础的运算还是要看CPU

但是一般而言,绝大多数人使用I3左右的CPU已经完全足够,根本没有需要GPU来加速计算机的必要
而不能满足需要的CPU的计算机,更没有什么给力的GPU来可以加速计算机

所以,理论是可以,而现实嘛
可否使用GPU首先需要程序支持,没需求自然不会有人浪费精力去做

非专业软件外最多就有点GPU算密码什么的

最后
这是我的分布计算平台boinc的截图
可以看到这个叫GPUGRID的高性能生物分子模拟项目,他的任务支持GPU,所以他使用了,而不支持的,则没有

0 0

Johnny小俊Android系统软件工程师、分析化学硕士

2014-05-19 14:41

这个问题应该at一下国内第一本CUDA教程的作者@樟树

0 0

算法的不同,线路设计也不同,假如CPU和GPU都融合在一起,应该有两种方案可以解决:神经元处理器、量子处理器。。。顺便BS一下@果壳问答 为什么我的果壳提问就不行?

0 0

光拼GPU并行能力的话N家CUDA还是一个非常不错的选择的。。
但是你要是说拼CPU+GPU集成的话,个人更看好AMD。。
产品上APU性价比、架构、第三方支持都摆在那儿。。
NV和ATI在各自的道路上匆匆见面又渐行渐远了。

1 3

GPU的处理精度不如CPU,记得是小数点后3位,再以后的位数其实就是随机数了。而且Cuda有个把数据从内存搬到显存,算好再搬回来的过程,所以并不是所有任务都适合用GPU加速。

0 7

每次看到首页图片滚进来,却发现都是文字、看不懂也无需懂的文字。

以为图片是一台比特币挖矿机,搜索后,是一台配备25片GPU的Linux群集,可以在6小时内破解Windows密码。


1 8



八音盒是最原始的“cpu”!程序存储、程序控制!嗯!

0 0

一眼扫过去还以为是G CUP和C CUP之间怎么转换...

查看更多

添加回答

登录 后回答问题,你也可以用以下帐号直接登录

相关问答

关于我们 加入果壳 媒体报道 帮助中心 果壳活动 家长监控 免责声明 联系我们 移动版 移动应用

©果壳网    京ICP证100430号    京网文[2018] 6282-492号    新出发京零字第朝200003号     京公网安备11010502007133号

违法和不良信息举报邮箱:jubao@guokr.com    举报电话:18612934101    网上有害信息举报专区    儿童色情信息举报专区