通过线程使用向量单元

Posted

技术标签:

【中文标题】通过线程使用向量单元【英文标题】:Using vector units through threading 【发布时间】:2016-06-09 00:46:26 【问题描述】:

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

【问题讨论】:

【参考方案1】:

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

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

对于受内存带宽限制的问题,在每个线程中使用 SIMD 可能意味着您只使用几个线程而不是多个线程来饱和内存带宽,但每个内核都有自己的私有 L1/L2 缓存(例如 Intel SnB 中的 256kiB L2 -家庭核心)。因此,如果您可以适当地缓存块(也称为循环平铺),则每个线程都可以遍历您的工作集中的一小块,该工作集在该核心的本地缓存中保持热状态。


对于不向量化的问题,是的,多线程肯定会有所帮助。不过,每个内核几乎都是独立的,因此避免 SIMD 并不能真正帮助您提高各个线程的每线程性能。

这个想法大多是假的:

我可以通过启动 8 个线程来获得一些好处,每个线程使用 1 个单元

不过,这并不完全是假的:Hyperthreading 在共享同一个物理内核的两个线程因内存延迟或分支错误预测(而不是 ALU 执行端口、缓存大小或内存)等瓶颈时工作得更好带宽)。

有关更多低级内容,请参阅 Agner Fog's optimization guides 以及 x86 标签 wiki 中的其他链接。


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

有关重新设计代码以使其对 SIMD 友好的示例,请参阅 the slides from a SIMD talk。

【讨论】:

以上是关于通过线程使用向量单元的主要内容,如果未能解决你的问题,请参考以下文章

通过引用向量传递的线程函数启动缓慢

C++:在多个线程中访问同一数组/向量的不同单元是不是会产生数据竞争?

在R向量中“向下”复制单元格值的惯用方法[重复]

为啥我的多线程并行求和函数的向量受限于线程数?

在函数中传递向量元素[关闭]

并发 任务执行