如果我们有 GPGPU,为啥还要使用 SIMD? [关闭]

Posted

技术标签:

【中文标题】如果我们有 GPGPU,为啥还要使用 SIMD? [关闭]【英文标题】:Why use SIMD if we have GPGPU? [closed]如果我们有 GPGPU,为什么还要使用 SIMD? [关闭] 【发布时间】:2014-09-02 18:46:15 【问题描述】:

现在我们有了使用 CUDA 和 OpenCL 等语言的 GPGPU,多媒体 SIMD 扩展 (SSE/AVX/NEON) 是否仍然有用?

我最近阅读了一篇关于如何使用 SSE 指令来加速排序网络的文章。我认为这很简洁,但是当我告诉我的计算机拱教授时,他笑着说在 GPU 上运行类似的代码会破坏 SIMD 版本。我不怀疑这一点,因为 SSE 非常简单,而且 GPU 是大型高度复杂的加速器,具有更多的并行性,但它让我思考,在很多场景中,多媒体 SIMD 扩展是否比使用 GPU 更有用?

如果 GPGPU 让 SIMD 变得多余,英特尔为什么要增加对 SIMD 的支持? SSE 是 128 位,现在 AVX 是 256 位,明年将是 512 位。如果 GPGPU 可以更好地处理具有数据并行性的代码,为什么英特尔要推动这些 SIMD 扩展?他们或许能够将同等资源(研究和领域)放入更大的缓存和分支预测器,从而提高串行性能。

为什么使用 SIMD 而不是 GPGPU?

【问题讨论】:

FWIW,英特尔似乎有意将 SIMD 大小增加到与 GPU 宽度相同(甚至更长)的程度。即合并 CPU 和 GPU。 @Mysticial 啊,是吗?你有一些我可以阅读的参考资料吗? 英特尔的 OpenCL 实现使用 SSE 和 AVX 进行了优化,实际上提供了相当不错的加速(在他们的 CPU 上而不是 Xeon Phi 上)。 SIMD / AVX / NEON 不会去任何地方,而是飘到后台。他们可能会为各种前端(如 OpenCL)做繁重的工作。 @Mysticial,根据 Agner Fog 的微架构手册,英特尔计划达到 1024,但没有进一步的计划。 设置 gpgpu 需要时间,而 simd 版本可能已经完成的时间。 gpgpu 启动后很快,但工作量的大小可能不值得。 【参考方案1】:

绝对 SIMD 仍然适用。

首先,SIMD 可以更轻松地与标量代码互操作,因为它可以直接读取和写入相同的内存,而 GPU 需要将数据上传到 GPU 内存才能访问。例如,通过 SIMD 对 memcmp() 之类的函数进行矢量化很简单,但通过将数据上传到 GPU 并在那里运行来实现 memcmp() 则很荒谬。延迟会很严重。

其次,SIMD 和 GPU 都不擅长处理高度分支的代码,但 SIMD 不那么糟糕。这是因为 GPU 将多个线程(“warp”)分组在单个指令调度程序下。那么当线程需要采用不同的路径时会发生什么:一个 if 分支在一个线程中采用,而 else 分支在另一个线程中采用?这被称为“分支分歧”,它很慢:所有“if”线程在“else”线程等待时执行,然后“else”线程在“if”线程等待时执行。 CPU 内核当然没有这个限制。

结果是 SIMD 更适合所谓的“中间工作负载”:最大中等大小的工作负载,具有一些数据并行性、访问模式的一些不可预测性和一些分支性。 GPU 更适合具有可预测的执行流程和访问模式的大型工作负载。

(还有一些外围原因,比如更好地支持 CPU 中的双精度浮点。)

【讨论】:

感谢您提供这些见解。关于您关于将数据“上传”到 GPU 的观点。似乎 AMD 的加速处理单元在与 CPU 内核相同的芯片上集成了一种 GPGPU。我不确定细节,但我认为它们共享 L2 或 L3 缓存。你认为这个论点也适用于这样的设备吗? 您在 CUDA / OpenCL 中提出了分支分歧,并说“CPU 核心”没有这个限制。这是一个不公平的说法。首先,SIMD 指令按内核运行。您可以在 SIMD 代码中根本没有 if / else 语句。您必须解压缩数据并单独执行操作,与您提到的分支分歧相比,这可能会变得更糟或更糟。 我一直想问类似的问题。我认为 GPU 基本上是具有许多慢速“核心”的大宽度 SIMD 设备? SIMT 真的不是软件而不是硬件。我的意思是每个“tread”似乎都不同,但它使用的是 SIMD,SIMD 单元中的每个其他线程都必须等待其他线程。我使用带有 AVX 的 mm256_movemask_epi8 做这样的事情。 在某些情况下确实需要解包,但不是全部,例如在线程 ID 上进行分支。或者考虑一下 memcmp 示例:所有需要“解包”的是寄存器的单个摘要位。当然,分支本身不是 SIMD 指令,但那是因为它不一定是:SIMD 可以轻松地将其卸载到 CPU 的分支机器上。 GPU 没有那么奢侈。 SIMD 仍然优于 GPU 的一个很好的例子是视频编码。搜索空间太大,一旦排除了对块进行编码的可能方法,您就需要根据比较结果进行分支。【参考方案2】:

GPU 有可控的专用缓存,CPU 有更好的分支。除此之外,计算性能依赖于 SIMD 宽度、整数核心密度和指令级并行度。

另一个重要参数是数据到 CPU 或 GPU 的距离。 (您的数据可能是离散 GPU 中的 opengl 缓冲区,您可能需要在使用 CPU 计算之前将其下载到 RAM,当主机缓冲区位于 RAM 中并需要在离散 GPU 上计算时可以看到相同的效果)

【讨论】:

好吧,在排序示例中,我认为如果 CPU 之后使用排序后的数组,这可能会很有用。但我的教授认为最好把它交给 GPU 并重新排序。他的研究是 GPGPU 的东西,所以我想他有偏见,但仍然......我有我的怀疑。 要排序的数组的长度是多少,排序的复杂度是多少?

以上是关于如果我们有 GPGPU,为啥还要使用 SIMD? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

为啥内核中不使用 SIMD 指令?

为啥这个 SIMD 乘法不比非 SIMD 乘法快?

如果我们可以简单地覆盖超类的方法或使用抽象类,为啥还要使用接口? [复制]

为啥 OpenMP 'simd' 比 'parallel for simd' 有更好的性能?

为啥刷新令牌更安全?如果刷新令牌也可能被盗,为啥我们还要使用它?

为啥并行 SIMD/SSE/AVX 需要置换?