使用CPU代替GPU有什么好处?


63

我一直在研究处理器和图形卡,但我发现GPU比CPU快得多。我在这篇文章中读到,在某些情况下,使用2年的Nvidia GPU优于3.2GHz Core I7 Intel处理器14倍。如果GPU这么快,为什么开发人员不将它们用于游戏中的每个功能?GPU是否可以做图形以外的任何事情?


17
如果您在游戏中将所有内容转移到GPU,而CPU几乎没有做任何事情,那么可以通过将部分负载放回到CPU上来提高性能。
Tetrad

3
您的GPU可能比您的CPU更好,但是我认为您的显卡不比您的主板好(并且我不会将操作系统与驱动程序进行比较)
e-MEE

27
GPU is faster than a CPU这是一个错误的神话,许多人在看到基于专门针对GPU的问题的基准测试(这类问题称为“尴尬的并行问题”)后被人们相信,请参阅我对以下SuperUser问题的回答:我们为什么仍在使用CPU而不是GPU?
Lie Ryan


5
一个好处是,每台计算机都有一个CPU :)
Tim Holt

Answers:


50

“我读过F1赛车比我们在街上开车要快。为什么人们不使用F1赛车呢?” 好吧...这个问题的答案很简单:F1汽车无法像大多数汽车一样快地折弯或转弯(在这种情况下,最慢的汽车可以击败F1)。GPU的情况非常相似,它们擅长遵循直线处理,但是在选择不同的处理路径时却不太好。

在GPU中执行的程序必须并行执行多次时才有意义,例如,当您必须将纹理A中的所有像素与纹理B中的像素混合在一起,然后将它们全部放入纹理C中时。一个CPU,将按以下方式处理:

for( int i =0; i< nPixelCount; i++ )
     TexC[i] = TexA[i] + TexB[i];

但这在您必须处理大量像素时很慢,因此GPU不用上面的代码,而只使用下一个:

     TexC[i] = TexA[i] + TexB[i];

然后用该程序填充所有内核(实际上是将程序复制到内核),并i为每个内核分配一个值。然后是它来自于GPU的魔法,让所有内核执行程序的同时,使很多操作比线性CPU程序可以做的更快。

当您必须以相同的方式处理大量小输入时,这种工作方式是可以的,但是当您必须编写可能具有条件分支的程序时,这种方法确实很糟糕。现在,让我们看一下CPU进行某些状态检查时的操作:

  • 1:执行程序直到第一个逻辑操作
  • 2:评估
  • 3:从比较的内存地址结果继续执行(与JNZ asm指令一样)

这对于CPU设置索引来说是非常快的,但是对于GPU而言,设置索引要复杂得多。由于GPU的强大功能来自于同时执行同一条指令(它们是SIMD内核),因此必须同步它们才能利用芯片架构。必须准备GPU来处理分支意味着或多或少:

  • 1:制作仅跟随分支A的程序版本,并在所有内核中填充此代码。
  • 2:执行程序,直到执行第一个逻辑操作
  • 3:评估所有元素
  • 4:继续处理分支A之后的所有元素,使选择路径B的所有进程排队(内核中没有程序!)。现在所有选择了路径B的内核都将变为IDLE !!!-最坏的情况是单个内核正在执行,其他所有内核都在等待。
  • 5:完成所有“ A”处理后,激活程序的B分支版本(通过将其从内存缓冲区复制到一些小型核心内存中)。
  • 6:执行分支B。
  • 7:如果需要,请混合/合并两个结果。

此方法可能会因很多因素而有所不同(例如,一些很小的东西分支可以运行而无需这种区别),但是现在您已经知道为什么分支会成为问题。GPU缓存非常小,您不能简单地以线性方式从VRAM执行程序,它必须将一小段指令复制到要执行的内核,并且如果您有足够多的分支,则GPU大部分将比执行停止像大多数程序一样,即使执行多个线程,执行仅跟随一个分支的程序时,出现任何意义的代码都没有意义。与F1的示例相比,这就像必须在每个转弯处打开制动降落伞,然后下车将它们包装回车内,直到您要再次转弯的下一个转弯或找到红色的信号灯(下一个转弯)最有可能的)。

当然,当然还有其他架构在逻辑运算方面的表现如此出色,便宜得多,更可靠,经标准化,知名度高,省电等问题。如果没有软件仿真,较新的视频卡很难与较旧的视频卡兼容。即使来自同一制造商,它们之间也可以使用不同的asm指令,并且目前大多数计算机应用程序都不需要这种类型的并行体系结构,即使他们需要它们,也可以通过标准api(例如OpenCL)使用电子商务或通过图形API提及。可能在几十年内,我们将拥有可以取代CPU的GPU,但我认为这种情况不会很快发生。

我推荐AMD APP的文档,该文档对它们的GPU架构进行了很多解释,并且在CUDA手册中还介绍了NVIDIA的文档,这对我的理解很有帮助。我仍然不了解某些事情,而且我可能会弄错了,也许知道更多的人可以确认或拒绝我的发言,这对我们所有人都非常有用。


6
奇怪的比喻,但这是一个好点the fastest isn't always the fastest
Lie Ryan

1
谢谢!我认为这是一个有趣的话题,因为它将许多游戏编程概念与硬件工作方式绑定在一起,这在当今的高级语言领域已被人们遗忘。我还想添加一些其他内容,但是写答案已经花了一些时间,所以我稍后会尝试更新它,例如CPU的“保护模式”功能,内存总线速度等,但是我希望可以澄清一下在GPU中执行所有操作的一些技术缺陷。
Pablo Ariel

6
如果准确的话,这个比喻会更好。F1赛车具有强大的制动能力,这使它们可以进一步保持高速行驶,而不是提前开始制动。尽管转弯半径可能不适合停车场,但由于下压力较大,因此高速转弯也更好。更好的原因可能包括缺乏存储空间,后视镜,空调,巡航控制系统,对元素的保护,乘客座椅,悬吊系统和地面间隙,以应对恶劣的道路,或客车常见的其他各种问题。
GargantuChet

5
@Pablo Ariel我在回应以下声明:“ F1赛车不能像大多数赛车一样快地折断或转弯”。您建议F1赛车只能沿直线加速,在转弯或减速期间效果不佳。但是F1赛车实际上可以比“大多数赛车”更快地制动,并且在高速转弯方面表现出色。
GargantuChet

4
如果您使用的是Dragsters而不是F1赛车
此类

32

GPU是很好的并行任务。如果您正在运行并行任务,那太好了。

游戏是关于最少并行化的应用程序。考虑一下主要的游戏循环。AI(假设玩家被当作AI的特例处理)需要响应物理检测到的碰撞。因此,它必须随后运行。或者至少,物理学需要在物理学系统的边界内调用AI例程(由于许多原因,这通常不是一个好主意)。图形必须等到物理运行后才能运行,因为物理会更新对象的位置。当然,AI也需要在渲染之前运行,因为AI可以生成新对象。在AI和播放器控制之后需要运行声音

一般而言,游戏可以以很少的方式进行线程化。图形可以在线程中分离出来。游戏循环可以在图形线程中推送大量数据,然后说:渲染此数据。它可以进行一些基本的插值,因此主游戏循环不必与图形保持同步。声音是另一个主题。游戏循环中说“播放”,然后播放。

在那之后,这一切开始变得痛苦。如果您具有复杂的路径算法(例如RTS的),则可以对它们进行线程化。算法可能需要花费几帧才能完成,但至少是并发的。除此之外,这非常困难。

因此,您正在研究4个线程:游戏,图形,声音以及可能的长期AI处理。那不多。而这还不是几乎足够的GPU,它可以有数百个线程在飞行一次。这就是使GPU发挥性能的原因:能够立即利用所有这些线程。游戏根本无法做到这一点。

现在,也许您可​​以进行一些操作。例如,AI通常彼此独立。因此,您可以一次处理数十个AI。直到您真正需要使它们相互依赖为止。那你就麻烦了。物理对象同样是独立的...除非它们之间没有约束和/或它们与某些物体碰撞。然后他们变得非常依赖。

另外,事实是GPU根本无法访问用户输入,据我了解,这对游戏来说很重要。因此必须提供。它也没有直接的文件访问或与操作系统对话的任何真实方法。因此,再次必须提供某种方式来提供此服务。哦,所有这些声音处理?GPU不发出声音。因此,那些必须先回到CPU,然后再到声音芯片。

哦,为GPU编码非常糟糕。很难做到正确,对于一种GPU架构而言,“正确”对另一种GPU架构而言可能是非常非常错误的。而且,这不仅仅是从AMD转向NVIDIA的事情。可以从GeForce 250切换到GeForce450。这是基本架构的变化。而且它很容易使您的代码运行不正常。不允许使用C ++,甚至C。最好的选择是OpenCL,它有点像C,但是没有一些优点。喜欢递归。没错:GPU上没有递归。

调试?哦,我希望您不喜欢IDE的调试功能,因为这些功能肯定不可用。即使您正在使用GDB,也要吻别。您必须诉诸printf调试...等等,printfGPU 上没有。因此,您必须写入内存位置,并让您的CPU存根程序将它们读回。

没错:手动调试。祝你好运。

另外,您在C / C ++中使用的那些有用的库吗?也许您更喜欢使用XNA等.NET。管他呢。没关系,因为您不能在GPU上使用它们中的任何一个。您必须从头开始编写所有代码。而且,如果您已经有一个代码库,那就很难了:该重写所有代码了。

是的。实际上为任何复杂类型的游戏做的事情都是可怕的。而且它甚至都行不通,因为游戏的并行性不足以提供帮助。


21

为什么不那么容易回答-需要注意的是,GPU是专用处理器,实际上并没有像常规CPU这样的通用用途。由于具有这种专业性,因此GPU可以为它专门设计(和优化)的性能胜过CPU,这并不奇怪,但这并不一定意味着它可以代替通用CPU的全部功能和性能。

我怀疑开发人员之所以会这么做是出于多种原因,其中包括:

  • 他们希望图形速度尽可能快,质量最高,并且使用宝贵的GPU资源可能会对此产生干扰。

  • 可能必须编写GPU特定的代码,这可能会给当前游戏(或应用程序)的整体编程带来额外的复杂性。

  • GPU通常无法访问网卡,键盘,鼠标和操纵杆等资源,因此无论如何它都无法处理游戏的各个方面。

回答问题的第二部分: 是的,还有其他用途。 例如,SETI @ Home之类的项目(可能还有其他BOINC项目)正在使用GPU(例如nVidia的GPU)进行高速复杂计算:

  在NVIDIA GPU上运行SETI @ home
  http://setiathome.berkeley.edu/cuda.php

我喜欢你的问题,因为它提出了一个有趣的主意。


18

CPU更加灵活,通常更容易编程,它们可以更快地运行单个线程。

尽管可以对现代GPU进行编程以解决几乎所有任务,但它们只有利用并行架构才能获得速度优势。高度重复的“简单”任务通常是这种情况。我们编写的许多代码都无法正常分支,无法在GPU上高效运行。

最重要的是,您最终可能会花费大量时间来优化不同图形芯片的代码。尽管OpenCL可用于使相同的代码在许多不同的图形芯片上运行,但您将以这种速度优势交换一些便利。

从游戏程序员的角度来看,我们通常也希望我们的游戏在具有较少图形卡的计算机上运行。某些集成芯片没有所需的可编程性,但如果这样做,它们的速度太慢,以至于即使对于他们本应擅长的工作,它们也不会在很大程度上击败处理器。当然,如果您确实为游戏开发了低端GPU,那么图形渲染将为您带来急需的处理能力。

确实,前景是不错的,但是当您制作游戏而不是破解密码时,在大多数情况下,实际的问题超过了好处。


6

GPU很难编程。您应该搜索如何在GPU上对列表进行排序。许多论文都试图做到这一点。

使用具有一个线程的CPU很容易,使用多线程则更困难,由于PVM或MPI很难使用许多具有并行库的计算机,而使用GPU则最困难。


4

除了Randolf Richardson回答的内容以外,GPU处理器还无法自行处理某些特定功能。例如,某些图形内存管理命令由CPU处理,因为GPU无法处理它们。

还有另一个重要原因,GPU设计用于多线程计算。这意味着GPU制造商只要想增加计算能力就可以轻松添加内核。但是有许多任务不能分为较小的问题,如计算斐波纳契数列中的第n个数。在这些情况下,CPU更快,因为它针对单线程任务进行了优化。


4

有很多答案表明,GPU只能更快,因为它们可以并行处理任务。这有点夸大了这个问题。由于其他原因,GPU可能更高效,例如能够具有更多限制性的内存访问,不必支持那么多数据类型,能够具有更高效的指令集等。早期的GPU仍然只能在1个像素处绘制1个像素。一次,但是事实是他们每个周期可以做1个,这一点很重要。

真正的差异是因为它们是2种不同类型的机器,它们经过定制以在不同的任务类别中表现良好,这些任务看似相似,但实际上却完全不同。这就像将飞机与汽车进行比较。飞机的最高速度要高得多,但是在使用方式上有更多限制。在任何一种情况下您都可以进行相同的旅程时,这架飞机似乎更为优越。


关于飞机的类比是一个很好的(+1),但是对于支持不同数据类型的CPU来说,实际上更多的是高级语言概念,因为CPU(至少在Intel领域是这样)以非常基本的形式(例如,位,字节,字,dword等)的数据。有一些紧密循环的指令可以扫描或复制以零字节结尾的数据,但是在这些实例中的数据并没有被CPU真正识别为特定类型(不是以零结尾的数据块)在这些循环的上下文中)。
兰道夫·理查森2011年

@Randolf:CPU具有不同的指令和寄存器,用于处理不同的低级数据类型(例如,带符号对无符号,整数对浮点)。在8086以及实际上大多数现代体系结构上就是这种情况,而且并非完全免费。
Kylotan

我敢肯定,他们仍然在底层架构中进行很多线性处理。从编程的角度来看,它只需要向GPU发出指令,但由于内核对其他硬件(例如从内存中读取)不是并行的,因此它们不能完全并行执行,因为它们可能会在单个GPU上向单个内核提供数据一个时间。
Pablo Ariel

3

开发人员确实将GPU用于他们擅长的所有功能。他们使用CPU来完成所有他们擅长的功能。是什么让您认为他们没有?

GPU擅长执行可大规模并行化的任务,并且需要大量的计算,而内存需求低或时间相关性高,决策量很少。这包括渲染图像,物理模拟(粒子,碰撞,布料,水,反射)等。因此,这正是现代游戏使用GPU的目的。

CPU擅长于无法很好并行化且需要大量决策的任务。即使只有适度的时间相关性,它们也可以忍受较高的内存需求。这包括人工智能,用户界面,磁盘和网络I / O等。因此,这正是现代游戏使用CPU的目的。


1

回读是我偶尔会更喜欢CPU的另一个原因。不是在带宽方面(因为GPU-> CPU带宽在现代硬件上就不再是问题),而是在流水线停滞方面。如果您需要从计算中取回结果并对它们做一些有趣的事情或有用的事情,那么使用GPU并不是明智的选择(通常情况下-在某些特殊情况下它仍然可以适用),因为回读将始终需要GPU停止其正在执行的操作,刷新所有待处理的命令并等待回读完成。这可能会降低性能,以至于不但消除了使用GPU的好处,而且实际上可能会变得相当慢。


0

这是一个老话题,但是最近发表的这篇文章可能会回答这个问题。这篇发表在ACM Computing Surveys 2015上的论文表明,每个CPU和GPU都有其独特的优势,因此,本文为从“ CPU与GPU之争”转向“ CPU-GPU协作计算”范例提供了理由。

CPU-GPU异构计算技术概述

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.