将 uint64_t 数组转换为 __m256i

标签 c avx avx2

我有四个 uint64_t 数字,我希望将它们组合为 __m256i 的一部分,但是,我不知道如何进行此操作。

这是一种尝试(其中 raxrbxrcxrdxuint64_t):

uint64_t a [4] = {rax,rbx,rcx,rcx};

__m256i t = _mm256_load_si256((__m256i *) &a);

最佳答案

如果您已经有一个数组,那么绝对使用_mm256_loadu_si256(或者甚至对齐版本,_mm256_load_si256,如果您的数组是alignas(32)。)但通常不要创建一个数组只是为了存储或重新加载。


使用_mm_set内在函数并让编译器决定如何做。请注意,它们首先采用编号最高的元素作为参数:例如

__m256i vt = _mm256_set_epi64x(rdx, rcx, rbx, rax);

您通常不希望 asm 看起来像标量存储 -> vector 加载 C 源代码,因为这会产生存储转发停顿。

在这种情况下,gcc 6.1“看穿”本地数组(并使用 2x vmovq/2x vpinsrq/1x vinserti128),但是它仍然生成代码以将堆栈对齐到 32B。 (尽管它不是必需的,因为它最终不需要任何 32B 对齐的本地变量)。

正如您在 Godbolt Compiler Explorer 上看到的那样,两种方式的实际数据移动部分是相同的,但是数组方式有一堆浪费的指令,gcc 在决定避免源暗示的坏方式后未能优化掉这些指令。

_mm256_set_epi64x 适用于 32 位代码(至少使用 gcc)。您将获得 2x vmovq 和 2x vmovhps 来对 xmm 寄存器的上半部分执行 64 位加载。 (将 -m32 添加到 godbolt 链接的编译选项中)。

关于将 uint64_t 数组转换为 __m256i,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38165525/

相关文章:

c - 如何给每个人写权限?

c - 指向 C 中 const 字符串的指针

连续相同的 "printf"调用产生不同的输出

c++ - 在 Mavericks 上编译 AVX2 程序

c++ - AVX intrinsic _mm256_cmp_ps 是否应该在 true 时返回 NaN?

c++ - 英特尔 AVX : Why is there no 256-bits version of dot product for double precision floating point variables?

c - 从动态分配的内存打印时值发生变化

assembly - 英特尔 IACA 分析器改变了组装?

c++ - 使用 SSE 和 AVX 查找矩阵中的最大元素及其列和行索引

c++ - 打乱 __m256i vector 的元素