64 位特定 simd 内在

Posted

技术标签:

【中文标题】64 位特定 simd 内在【英文标题】:64-bit specific simd intrinsic 【发布时间】:2010-12-08 16:31:28 【问题描述】:

我在 SSE2 中使用以下联合声明。

typedef unsigned long uli;  
typedef uli v4si __attribute__ ((vector_size(16)));  
typedef union  
  
    v4si v;  
    uli data[2];  
 uliv;  

uliv a, b, c;

这个想法是为每个 a 和 b 分配两个无符号长变量(64 位长),对它们进行异或并将结果放在 c 中。

显式分配 (a.data[0] = something) 在这里有效,但需要更多时间。

我打算使用内在函数。如果我使用_mm_set_epi64 (unsigned long x, unsigned long y),它会要求__m64 变量。如果我转换这些变量(__m64)x 并且它工作正常,但它给出了错误的结果。

for (k = 0; k < 10; k++)  
  
    simda.v = _mm_set_epi64 (_mulpre1[u1][k], _mulpre2[u2][k]);  
    simdb.v = _mm_set_epi64 (res1[i+k], res2[i+k]);  
    simdc.v = _mm_xor_si128 (simda.v, simdb.v);  

以上代码报错:

/usr/lib/gcc/x86_64-linux-gnu/4.4.3/include/emmintrin.h:578: note: expected ‘__m64’
but argument is of type ‘long unsigned int’

您能否建议一些替代方案(内在)?

【问题讨论】:

【参考方案1】:

确定unsigned long 在您的系统上是 64 位吗?从&lt;stdint.h&gt; 使用unsigned long long 或更好的uint64_t 可能更安全。

在我的系统上_mm_set_epi64 接受两个unsigned long long 参数并返回一个__m128i

从您的问题中不清楚您是只想 (a) 异或两个 64 位值还是 (b) 异或两个 2 x 64 位值的向量?

对于情况 (a),只需使用标量代码,例如

uint64_t a, b, c;

c = a ^ b;

对于情况 (b),您不需要联合等,只需这样做:

__m128i va, vb, vc;

va = _mm_set_epi64(a1, a2);
vb = _mm_set_epi64(b1, b2);
vc = _mm_xor_si128(va, vb);

【讨论】:

1. unsigned long 在我的机器中是 64 位。情况(b)将适用于我的程序。 a1,a2 是无符号长元素,但我收到以下错误(没有 __m64 强制转换):/usr/lib/gcc/x86_64-linux-gnu/4.4.3/include/emmintrin.h:578:注意:预期' __m64' 但参数的类型为 'long unsigned int' @anup: 是循环的一部分,即您是否有需要异或的值数组。如果是这样,那么可能有更好的整体解决方案。 是的,它是循环的一部分……更好的解决方案是什么?情况是这样的,对于每次迭代,我从两个不同的数组中获取两个值(不一定是相同的索引),从两个不同的数组中获取另外两个值,对它们进行异或并将它们放入第二组数组中.. @anup: 另请注意,对于较新版本的 gcc 和 emmintrin.h,您可能需要使用 _mm_set_epi64x 而不是 _mm_set_epi64。从 gcc 4.3 开始,您可能还需要 gcc -flax-vector-conversions 来编译旧的 SSE 代码。 @anup:在使用 _mm_set_epi64 时,您可能会在后台生成大量标量指令和内存访问,因此您的 SIMD 指令将没有什么好处。或许将代码作为一个新问题发布,然后我们可以看看我们是否可以正确优化它。

以上是关于64 位特定 simd 内在的主要内容,如果未能解决你的问题,请参考以下文章

英特尔 SIMD 内在函数:_mm256_i64scatter_pd

有没有一种有效的方法来使用 SIMD 内在函数来获取 SIMD 寄存器中的第一个非零元素?

我可以将SIMD内在函数用于在云上运行的软件吗?

Cython 和 SIMD 内在函数:防止 SIMD 内在函数的参数转换为 python 对象

与 SIMD 内在函数进行比较和交换

aarch64 上未对齐 SIMD 加载/存储的性能