为什么 GPU 在数值计算中的性能比 CPU 更高?更糟糕的是分支?有人可以给我一个详细的解释吗?
2 回答
不确定您到底在寻找什么。假设这是为了一般理解为什么这样做而不是另一种方式。本文对您的问题提供了合理的理解(用外行的话):
https://en.bitcoin.it/wiki/Why_a_GPU_mines_faster_than_a_CPU
简而言之:
一个 CPU 内核每个时钟可以执行 4 条 32 位指令(使用 128 位 SSE 指令)或通过 AVX(256 位)执行 8 条,而像 Radeon HD 5970 这样的 GPU 每个时钟可以执行 3200 条 32 位指令(使用它的 3200 个 ALU 或着色器)。这是每个时钟 800 倍(或 AVX 的情况下为 400 倍)指令的差异。截至 2011 年,最快的 CPU 拥有多达 6、8 或 12 个内核和更高频率的时钟(2000-3000 MHz 对比 Radeon HD 5970 的 725 MHz),但一个 HD5970 仍然比 Radeon HD 5970 快五倍以上四个 2.3GHz 的 12 核 CPU(这也将使您花费大约 4700 美元,而不是 HD5970 的 350 美元)。
GPU 是为特定任务而设计的,即渲染需要大量计算的 3D 图形。因此,某些应用程序将“数字运算”卸载到 GPU,就像大多数现代浏览器一样。而对于分支功能,由于 CPU 具有更好的“霸主”功能,因此任务由 CPU 保留(现在,谁知道他们以后会做什么)。
GPU 中的每个 SM 都是一个 SIMD 处理器,在 SIMD 的每个通道上执行不同的 warp 线程。一旦应用程序受到更多计算限制(一些内存访问)并且没有分支应用程序达到 GPU 的峰值 FLOPS。这是因为在分支时,GPU 会掩盖分歧的一侧并首先执行另一侧。两条路径都连续执行,使一些 SIMD 通道处于非活动状态,从而降低了性能。
我在Fung 的论文中包含了一个有用的图,该图可在上述参考资料中公开获得,以显示性能实际上是如何下降的:
图 (a) 显示了一个典型的 GPU 分支分歧发生在一个 warp 内部(这个样本中有 4 个线程)。假设您有以下内核代码:
A: // some computation
if(X){
B: // some computation
if(Y){
C: // some computation
}
else{
D: // some computation
}
E: // some computation
}else{
F: // some computation
}
G: // some computation
A 处的线程分为 B 和 F。如 (b) 所示,随着时间的推移,一些 SIMD 通道被禁用,性能下降。图 (c) 到 (e) 显示了硬件如何串行执行发散路径并管理发散。有关更多信息,请参阅这篇有用的论文,这是一个很好的起点。
矩阵乘法或 N-Body 模拟等计算受限应用程序可以很好地映射到 GPU 并返回非常高的性能。这是因为它们很好地占据了 SIMD 通道,遵循流模型,并且有一些内存访问。