링커 오류가 발생하는 경우 신고되지 않은 내장 함수에 대한 경고를 무시한 것입니다.
현재 코드는 끔찍한 asm 컴파일의 위험이 있습니다. 벡터 이동 및 OR로 컴파일 된 경우 이미 하위 최적 코드로 컴파일됩니다. (업데이트 : 그것이 컴파일 된 것이 아닌 IDK의 아이디어입니다.)
2x _mm_cvtpd_epi32을 사용하여 각각 2 개의 하위 요소에 원하는 int를 갖는 두 개의 __m128i
벡터를 얻습니다. _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
MME는 SSE2 이상을 사용할 수있는 경우 거의 쓸모가 없습니다. 그냥 피하십시오. 일부 가이드는 sse 태그 위키를 참조하십시오.
Xcode가 최적화하지 않았습니다. 디스 어셈블리하면 _mm_cvtpd_pi32가 사용되고, _mm_set_epi64는 mov를 사용하여 값을 저장합니다. –
그래, 작동 : _mm_unpacklo_epi64 (_mm_cvtpd_epi32 (v2dLo), _mm_cvtpd_epi32 (v2dHi)) –