如果出现链接器错误,您可能会忽略有关未声明的内部函数的警告。
您当前的代码很有可能编译成糟糕的 asm。如果它编译为向量移位和 OR,则它已经编译为次优代码。 (更新:这不是它编译的结果,我不知道你是从哪里得到这个想法的。)
Use 2x _mm_cvtpd_epi32得到两个__m128i
每个向量的后 2 个元素都包含您想要的整数。使用_mm_unpacklo_epi64将这两个低半部分组合成一个向量,其中包含您想要的所有 4 个元素。
编译器输出来自Godbolt 编译器资源管理器上的 clang3.8.1。 (我认为 Xcode 默认使用 clang)。
#include <immintrin.h>
// the good version
__m128i pack_double_to_int(__m128d a, __m128d b) {
return _mm_unpacklo_epi64(_mm_cvtpd_epi32(a), _mm_cvtpd_epi32(b));
}
cvtpd2dq xmm0, xmm0
cvtpd2dq xmm1, xmm1
punpcklqdq xmm0, xmm1 # xmm0 = xmm0[0],xmm1[0]
ret
// the original
__m128i pack_double_to_int_badMMX(__m128d a, __m128d b) {
return _mm_set_epi64(_mm_cvtpd_pi32(b), _mm_cvtpd_pi32(a));
}
cvtpd2pi mm0, xmm1
cvtpd2pi mm1, xmm0
movq2dq xmm1, mm0
movq2dq xmm0, mm1
punpcklqdq xmm0, xmm1 # xmm0 = xmm0[0],xmm1[0]
# note the lack of EMMS, because of not using the intrinsic for it
ret
当SSE2及更高版本可用时,MMX几乎完全没有用;只是避免它。请参阅sse标记 wiki 以获得一些指南。