c++ - LLVM 中的 SIMD vector 内存加载

标签 c++ llvm simd llvm-ir avx

LLVM 中将数据从内存加载到 SIMD vector 的“正确”(即可移植)方式是什么?
查看 LLVM 的自动矢量化器为 x86 目标生成的典型 IR,模式似乎是:

  • 将指向标量类型(例如, double * )的指针位转换为相应的 vector 类型(例如, <4 x double>* ),
  • 从转换后的指针加载,同时考虑对齐问题(即,不使用 vector 类型的自然对齐方式,而是使用相应标量类型的对齐方式)。

  • 在 AVX 的情况下,这种模式很好地映射到 SIMD 内在函数,例如 _mm256_loadu_pd()和 friend 。但是,我不知道这种策略是否也适用于其他 ISA(例如 Neon、AltiVec)。
    我无法在 LLVM 文档中找到有关该主题的信息。我错过了一些明显的东西吗?

    最佳答案

    花了更多时间思考这个问题后,我相信可移植解决方案可能如下:

  • 以通常的(非 SIMD)方式从内存中一个一个地加载标量值,
  • 立即构建一个重复的 vector insertelement指示。

  • 类似地,为了将 SIMD vector 中的值存储到内存位置,通过 extractelement 将 vector 元素提取为标量。指令并一一存储。
    在我的实验中,LLVM 优化器总是成功地识别这些模式并将它们融合到直接的 SIMD 加载/存储指令中。
    然而,这种策略也会导致生成的 IR 大小显着膨胀,并导致编译时间下降。因此,目前我将坚持直接位播方法,如果位播方法在特定设置上失败,我可能会实现另一种方法作为后备。

    关于c++ - LLVM 中的 SIMD vector 内存加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63090216/

    相关文章:

    python - argv 的 ctypes 错误

    c++ - 如何将 WebAssembly 编译成常规汇编/ native 代码(或 Cpp 等)?

    function - 在 LLVM 函数中反向迭代基本 block

    c - 用于求幂的 SIMD 代码

    c++ - C++ 中的类属性变量

    c++ - Objective C 的 Xcode 6 上出现错误 'Undefined symbols for architecture x86_64 '

    c++ - 如何使用 LLVM pass 将变量设置为 volatile 或 const

    c++ - SSE2 打包的 8 位整数有符号乘法(高半) : Decomposing a m128i (16x8 bit) into two m128i (8x16 each) and repack

    c++ - 如何将两个_pd 转换为一个_ps?

    c++ - 从shared_ptr 得到一个正常的ptr?