Lbj*_*j_x 2 c c++ simd intrinsics avx
我正在使用AVX内在函数进行矢量化,我想将常量浮点数填充1.0到矢量中__m256.所以在一个寄存器中我得到了一个向量{1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}
有谁知道怎么做?
它类似于这个问题常量浮点数和SIMD
但我使用AVX而不是SSE
请参阅此处了解AVX内在函数加载和存储操作.您只需要声明一个浮点数组,一个AVX向量__m256,然后使用适当的操作将float数组加载为AVX向量.
在这种情况下,指令_mm256_load_ps就是你想要的.
更新:如评论中所述,数据必须是32位对齐的.有关详细说明,请参阅英特尔数据对齐文档.根据彼得的评论,我已经使解决方案代码更加清晰.通过优化enabled(-O3),这将生成与Paul的答案相同的代码(也启用了优化).但是,如果没有启用优化,指令的数量是相同的,但是存储了所有8个浮点数,而不是Paul的答案中的单个浮点数.
这是修改后的例子:
#include <immintrin.h> // For AVX instructions
#ifdef __GNUC__
#define ALIGN(x) x __attribute__((aligned(32)))
#elif defined(_MSC_VER)
#define ALIGN(x) __declspec(align(32))
#endif
static constexpr ALIGN(float a[8]) = {1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f};
int main() {
// Load the float array into an avx vector
__m256 vect = _mm256_load_ps(a);
}
Run Code Online (Sandbox Code Playgroud)
您可以使用Godbolt交互式C++编译器通过一些编译器轻松检查汇编输出.
您可以在没有 const 数组的情况下使用它
pcmpeqw xmm0, xmm0
pslld xmm0, 25
psrld xmm0, 2
Run Code Online (Sandbox Code Playgroud)
请参阅 Agner Fog 的优化指南中创建其他常量的方法,13.10 生成常量 - 在 XMM 寄存器中制作浮点常量
pcmpeqw xmm0, xmm0 ; 1.5f
pslld xmm0, 24
psrld xmm0, 2
pcmpeqw xmm0, xmm0 ; -2.0f
pslld xmm0, 30
Run Code Online (Sandbox Code Playgroud)
也可以看看
最简单的方法是使用_mm256_set1_ps:
__m256 v = _mm256_set1_ps(1.0f);
Run Code Online (Sandbox Code Playgroud)