GPU 执行 "flow" 对比 CPU

GPU execution "flow" vs. CPU

在一般情况下,CPU 执行并行处理,将计算/问题分解为子问题,将它们分布并运行 在一个或多个套接字/服务器上的多个内核上并行处理它们.

GPU 上从加载数据到将结果发送回 CPU 的执行过程 "flow" 是什么?在 GPU 上执行和在 CPU 上执行之间的主要区别是什么?

我们应该将 GPU 视为 "kind of CPU with a higher (huge) number smaller cores" 还是在本质上存在其他差异?

CPU 和 GPU 并行处理的根本区别在于 CPU 是 MIMD(多指令-多数据),而 GPU 是 SIMD(单指令-多数据)。在多核 CPU 中,每个核都独立于其他核获取指令和数据,而在 GPU 中,一组核(通常为 32 或 64 个)只有一个指令流。虽然 32/64 内核只有一个指令流,但每个内核都在处理不同的数据元素(通常一起位于内存中;更多内容见下文)。这种 SIMD 执行意味着 GPU 内核以锁步方式运行。

由于上述原因,不能将 GPU 视为 "kind of CPU with a higher (huge) number smaller cores"。

为了支持 SIMD 执行(有时也称为宽执行),我们需要输入数据的宽提取。对于 32 宽执行,我们获取一个 contiguous 4B x 32 块 = 128B,它(通常)完全由 32 宽管道消耗。将此与 MIMD 多核进行对比,其中 32 CPU 个内核中的每一个都会获取一条单独的指令,然后从 32 个不同的缓存行加载。与 MIMD 相比,这种(宽)instruction/data 提取的 SIMD 特性可节省大量电量。因此,对于相同的功率预算,我们可以在 GPU 上放置比多核 CPU 更多的内核(=> 更多硬件并行性)。

GPU 的 SIMD 性质是由对非常多的输入元素执行完全相同的操作的应用程序驱动的(例如,图像处理,我们在 1024x768 图像的每个像素上应用过滤器)以便宽 instruction/data 获取效果很好。同时,每个内核的计算不同的应用程序(例如,当输入数据为零时采用 if(),或如果输入数据为 1 则采用 else())或每个内核需要从不同页面获取数据的应用程序无法利用GPU 的 SIMD 特性。

一个部分相关的事实是 GPU 支持流式传输(几乎为零数据重用)并具有大量数据并行性的应用程序(例如,images/videos)。流意味着我们不需要像 CPUs 这样的巨大缓存,并且大量数据并行性几乎完全减少了对 HW 一致性机制的需求。