Gid*_*eon 9 c++ sse intrinsics
在_mm_set_epi64和类似*_epi64指令似乎使用并依赖__m64类型.我想初始化一个类型的变量__m128,使其高64位为0,并将其低64位设置为x,其中x是类型uint64_t(或类似的无符号64位类型).这样做的"正确"方法是什么?
优选地,这应该以与编译器无关的方式完成.
要回答有关如何将64位值加载到XMM寄存器的低64位而将高64位归零的问题, _mm_loadl_epi64(&x) 将完全符合您的要求.
关于to _mm_set_epi64我曾经说过,看过Agner Fog的Vector Class Library的源代码可以回答关于SO的SSE/AVX的95%的问题.Agner为多个编译器以及64位和32位实现了这个(来自文件vectori128.h).请注意,MSVC 32位Agner的解决方案说"这是低效的,但其他解决方案更糟".我猜这就是Mysticial所说的"没有一个好方法可以做到这一点."
Vec2q(int64_t i0, int64_t i1) {
#if defined (_MSC_VER) && ! defined(__INTEL_COMPILER)
// MS compiler has no _mm_set_epi64x in 32 bit mode
#if defined(__x86_64__) // 64 bit mode
#if _MSC_VER < 1700
__m128i x0 = _mm_cvtsi64_si128(i0); // 64 bit load
__m128i x1 = _mm_cvtsi64_si128(i1); // 64 bit load
xmm = _mm_unpacklo_epi64(x0,x1); // combine
#else
xmm = _mm_set_epi64x(i1, i0);
#endif
#else // MS compiler in 32-bit mode
union {
int64_t q[2];
int32_t r[4];
} u;
u.q[0] = i0; u.q[1] = i1;
// this is inefficient, but other solutions are worse
xmm = _mm_setr_epi32(u.r[0], u.r[1], u.r[2], u.r[3]);
#endif // __x86_64__
#else // Other compilers
xmm = _mm_set_epi64x(i1, i0);
#endif
};
Run Code Online (Sandbox Code Playgroud)
最常见的"标准"内在函数是_mm_set_epi64x.
对于缺少的平台,_mm_set_epi64x您可以像这样定义替换宏:
#define _mm_set_epi64x(m0, m1) _mm_set_epi64(_m_from_int64(m0), _m_from_int64(m1))
Run Code Online (Sandbox Code Playgroud)