通过线程使用向量单元

Using vector units through threading

要使用矢量单元,例如 512 位宽同时对 8 个双精度值进行操作,是否需要单线程并使用 AVX 内在函数?如果我的程序不容易矢量化,我是否可以通过启动 8 个线程,每个线程使用 1 个单元来获得一些好处?

多线程和SIMD是正交的;如果您的问题具有大规模并行性,则可以使用多线程。如果它具有 SIMD 友好的并行性,则可以矢量化。通常你可以两者兼顾,这就是 .

的重点

多核 CPU 中的每个 CPU 核都有自己的一组向量执行单元。

在每个线程中使用 SIMD 可能意味着您只使用几个线程而不是多个线程来饱和内存带宽,以解决受内存带宽限制的问题,但每个内核都有自己的私有 L1/L2 缓存(例如 256kiB英特尔 SnB 系列内核中的 L2)。因此,如果您可以适当地缓存块 aka loop-tile,则每个线程都可以在您的工作集中的一小块上循环,该工作集在该核心的本地缓存中保持热状态。


对于不向量化的问题,是的,它当然可以帮助多线程。不过,每个内核几乎都是独立的,因此避免使用 SIMD 并不能真正帮助提高单个线程的每线程性能。

这个想法大部分是假的:

could i maybe get some of the benefit by launching 8 threads where each use 1 of the units

不过,这并不完全是假的:Hyperthreading 当共享同一物理内核的两个线程在内存延迟或分支预测错误(而不是 ALU 执行端口、缓存大小或内存带宽).

有关更多底层内容,请参阅 Agner Fog's optimization guides, and other links in the 标签 wiki。


将您的数据结构重新设计为对 SIMD 友好通常是可能的,但通常需要进行大量更改。希望您使用了一些包装器来抽象对数据结构的访问,这样您就可以更改它们的布局而无需触及大量代码。

有关将代码重新设计为 SIMD 友好的示例,请参阅 the slides from a SIMD talk