如果你有鏈接器錯誤,你可能會忽略關於未聲明的內部函數的警告。
你目前的代碼編譯可怕的asm的風險很高。如果它編譯爲向量移位和OR,它已經編譯爲次優代碼。 (更新:這不是它編譯的內容,IDK,你有這個想法。)
使用2x _mm_cvtpd_epi32獲得兩個__m128i
向量,您需要在每個元素的低2個元素中輸入整數。使用_mm_unpacklo_epi64將這兩個低半部分合併成一個具有所有4個元素的向量。從clang3.8.1 on the Godbolt compiler explorer
編譯器輸出。 (我認爲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。
Xcode沒有優化它。反彙編顯示正在使用_mm_cvtpd_pi32,_mm_set_epi64正在使用mov來存儲這些值。 –
是的,它的工作原理: _mm_unpacklo_epi64(_mm_cvtpd_epi32(v2dLo),_mm_cvtpd_epi32(v2dHi)) –