将uint64_t的数组转换为__m256i

时间:2016-07-03 00:00:51

标签: c avx avx2

我有四个uint64_t个数字,我希望将它们合并为__m256i的一部分,但是,我对如何解决这个问题感到迷茫。

此处有一次尝试(raxrbxrcxrdxuint64_t):

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

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

2 个答案:

答案 0 :(得分:1)

首先,确保您的CPU甚至支持这些AVX指令:Performing AVX integer operation

其次,从https://software.intel.com/en-us/node/514151开始,指针参数必须是对齐的位置。传统上在堆栈上分配的存储器地址是随机的,并且取决于先前调用的堆栈帧的大小,因此可能不对齐。

相反,只需使用内在类型__m256i 强制编译器来对齐它; OR ,根据https://software.intel.com/en-us/node/582952,在__declspec(align)数组上使用a

答案 1 :(得分:1)

使用_mm_set内在函数,让编译器决定如何操作。请注意,他们首先使用编号最高的元素的args:例如

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

您通常不希望asm看起来像您的标量商店 - > vector load C source,因为这会产生一个存储转发停顿。

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链接中的编译选项。)