是否可以结合 Rayon 和 Faster?

Posted

技术标签:

【中文标题】是否可以结合 Rayon 和 Faster?【英文标题】:Is it possible to combine Rayon and Faster? 【发布时间】:2018-07-09 20:01:56 【问题描述】:

Rayon 看起来非常适合集合的算法并行化,Faster 非常适合 x86 平台上的矢量化 (SIMD),例如 Vec<f32>。我试图将它们结合起来,迭代器似乎彼此不喜欢。有没有办法将这两个库用于可以同时受益于矢量化和并行化的算法?就像 Faster 示例中的这个:

let lots_of_3s = (&[-123.456f32; 128][..]).iter()
    .map(|v| 
        9.0 * v.abs().sqrt().sqrt().recip().ceil().sqrt() - 4.0 - 2.0
    )
    .collect::<Vec<f32>>();

【问题讨论】:

需要注意的是超线程内核。我的理解是这些虚拟内核没有自己的 SIMD 单元,因此您会与自己竞争,从而导致大量缓存抖动。 @Shepmaster:是的,可以真正用一个线程使整个核心的 SIMD 执行单元饱和的代码不需要超线程,但这种情况很少见。就像一个经过良好调整的 matmul 一样。甚至像 x264 和 x265(大量使用向量 ALU)这样的视频编解码器也可以通过使用每个物理内核的两个逻辑内核来获得轻微的加速,比如在 1080p 视频上的 Skylake i7-6700k 上 x264 -preset slower 可能有 15% 的加速。如果您的代码瓶颈在于延迟而不是吞吐量(例如,没有足够的累加器的减少),HT 可能是展示更多指令级并行性的好方法。 @Shepmaster: TL:DR: SMT(超线程的通用形式)是一种向每个物理内核公开更多指令级并行性的方法。具有独立迭代的循环往往不会带来太多好处,但隐藏缓存未命中延迟仍然会有所帮助,除非来自 2 个竞争相同缓存的线程的额外缓存压力导致更多未命中。 (一些微架构资源是静态分区的,例如英特尔 CPU 中的 ROB 和存储缓冲区,但缩小它们导致性能下降的可能性较小。) 嗯,我没有意识到有一个问题,这真是太好了。谢谢你们的cmets。 【参考方案1】:

您可以只使用 Rayon 的 par_chunks 并使用 Faster 处理每个块。

let lots_of_3s = (&[-123.456f32; 1000000][..])
    .par_chunks(128)
    .flat_map(|chunk| 
        chunk
            .simd_iter(f32s(0.0))
            .simd_map(|v| 
                f32s(9.0) * v.abs().sqrt().rsqrt().ceil().sqrt() - f32s(4.0) - f32s(2.0)
            )
            .scalar_collect()
    )
    .collect::<Vec<f32>>();

【讨论】:

以上是关于是否可以结合 Rayon 和 Faster?的主要内容,如果未能解决你的问题,请参考以下文章

Rayon 如何防止线程之间使用 RefCell<T>、Cell<T> 和 Rc<T>?

[LeetCode]141. Linked List Cycle

微软并发Key-Value存储库FASTER介绍

如何仅训练 RPN 以实现火炬视觉 Faster RCNN 与预训练主干

TensorFlow2深度学习实战(十七):目标检测算法 Faster R-CNN 实战

TensorFlow2深度学习实战(十七):目标检测算法 Faster R-CNN 实战