cpu vs gpu - 当cpu更好

tyn*_*ynk 16 cpu gpgpu cpu-architecture

我知道GPU比CPU快得多的例子.但存在很难并行化的算法(问题).当CPU可以克服GPU时,你能给我一些例子或测试吗?

编辑:

谢谢你的建议!我们可以对最流行的和最新的cpu和gpu进行比较,例如Core i5 2500k vs GeForce GTX 560 Ti.

我想知道如何比较它们之间的SIMD模型.例如:Cuda更准确地称SIMD为SIMD模型.但是SIMT应该与CPU上的多线程进行比较,后者在MIMD内核之间分配线程(任务)(Core i5 2500k提供4个MIMD内核).另一方面,这些MIMD内核中的每一个都可以实现SIMD模型,但这不是SIMT,我不知道如何比较它们.最后,具有并发内核执行的fermi架构可能被视为具有SIMT的MIMD内核.

Zk1*_*001 16

根据我的经验,我将总结CPU和GPU中并行程序之间在性能方面的主要差异.相信我,比较可以代代相传.所以我只想指出什么是好的,对CPU和GPU都不好.当然,如果你在极端情况下,即具有唯一不好的或好的方面做一个程序,它会运行肯定快在一个平台上.但是这些的混合需要非常复杂的推理.

主机程序级别

一个关键的区别是内存传输成本.GPU设备需要一些内存传输.在某些情况下,这种成本非常重要,例如,当您不得不经常转移一些大型数组时.根据我的经验,这个成本可以最小化,但将大部分主机代码推送到设备代码.您可以这样做的唯一情况是您必须在程序中与主机操作系统进行交互,例如输出到监视器.

设备程序级别

现在我们来看一个尚未完全揭示的复杂画面.我的意思是GPU中有许多尚未公开的神秘场景.但是,我们仍然在性能方面区分了CPU和GPU(内核代码).

我注意到很少有因素会对差异产生显着影响.

  • 工作量分配

GPU由许多执行单元组成,旨在处理大规模并行程序.如果你没有什么工作,说几个连续的任务,并把这些任务放在GPU上,那么很多执行单元中只有少数几个忙,所以会慢于CPU.另一方面,CPU更好地处理短期和顺序任务.原因很简单,CPU更复杂,能够利用指令级并行,而GPU利用线程级并行.好吧,我听说NVIDIA GF104可以做Superscalar,但我没有机会体验它.

值得注意的是,在GPU中,工作负载被分成小块(或OpenCL中的工作组),块以块的形式排列,每个块都在一个流处理器中执行(我使用的是NVIDIA的术语).但是在CPU中,这些块是按顺序执行的 - 我想不出除了单个循环之外的任何东西.

因此,对于具有少量块的程序,它可能在CPU上运行得更快.

  • 控制流程说明

分支对于GPU来说总是很糟糕.请记住,GPU更喜欢平等的东西.等块,块内的相等线程,以及经线内的相等线程.但最重要的是什么?

                            ***Branch divergences.***
Run Code Online (Sandbox Code Playgroud)

Cuda/OpenCL程序员讨厌分支差异.由于所有线程都被分成32个线程组(称为warp),并且warp中的所有线程都以锁步方式执行,因此分支差异将导致warp中的某些线程被序列化.因此,经线的执行时间将相应地成倍增加.

与GPU不同,CPU中的每个核心都可以遵循自己的路径.此外,由于CPU具有分支预测,因此可以有效地执行分支.

因此,具有更多扭曲差异的程序可能在CPU上运行得更快.

  • 内存访问指令

真的很复杂,所以让我们简单一点.

请记住,全局内存访问具有非常高的延迟(400-800个周期).因此,在旧一代GPU中,内存访问是否合并是一个关键问题.现在您的GTX560(Fermi)拥有更多2级缓存.因此,在许多情况下可以降低全局存储器访问成本.但是,CPU和GPU中的缓存不同,因此它们的效果也不同.

我能说的是,它真的取决于你的内存访问模式,你的内核代码模式(内存访问如何与计算交互,操作类型等),以告诉你是否在GPU或CPU上运行得更快.

但不知何故,你可以预期大量的缓存未命中(在GPU中)对GPU有很严重的影响(有多糟糕? - 这取决于你的代码).

此外,共享内存是GPU的一个重要特性.访问共享内存与访问GPU L1缓存一样快.因此,使用共享内存的内核将带来很多好处.

我还没有提到的其他一些因素,但在许多情况下,这些因素会对性能产生很大影响,例如银行冲突,内存事务大小,GPU占用率......