Visual c++ 如何在MSVC中有效地将两个m128d转换为一个m128i?

Visual c++ 如何在MSVC中有效地将两个m128d转换为一个m128i?,visual-c++,x86,64-bit,sse,mmx,Visual C++,X86,64 Bit,Sse,Mmx,将两个\uuum128d转换为一个\uuuum128i的唯一方法是先转换然后按位或“ing”吗 这对于x64构建中的Xcode来说是完全可以接受的 m128d v2dHi = .... m128d v2dLo = .... __m128i v4i = _mm_set_epi64(_mm_cvtpd_pi32(v2dHi), _mm_cvtpd_pi32(v2dLo)) 反汇编显示正在使用\u mm\u cvtpd\u pi32。但是,VisualStudio无法编译此文件,并抱怨链接器错误。V

将两个
\uuum128d
转换为一个
\uuuum128i
的唯一方法是先转换然后按位或“ing”吗

这对于x64构建中的Xcode来说是完全可以接受的

m128d v2dHi = ....
m128d v2dLo = ....
__m128i v4i = _mm_set_epi64(_mm_cvtpd_pi32(v2dHi), _mm_cvtpd_pi32(v2dLo))
反汇编显示正在使用
\u mm\u cvtpd\u pi32
。但是,VisualStudio无法编译此文件,并抱怨链接器错误。VS文档支持这一点,即x64不支持
\u mm\u cvtpd\u pi32


我并不太担心它不可用,但两次转换、一次移位、然后按位还是最快的方式?

如果出现链接器错误,可能会忽略关于未声明的内部函数的警告

您当前的代码有编译成可怕的asm的高风险。如果它编译为向量移位和OR,则它已经编译为次优代码。(更新:这不是它编译的目的,IDK你是从哪里得到这个想法的。)

使用2x获得两个
\uuuu m128i
向量,每个向量的低2个元素中包含所需的整数。用于将这两个较低的一半组合为一个向量,其中包含所需的所有4个元素


来自的编译器输出。(我认为Xcode默认使用clang)

#包括
//好版本
__m128i包双到整数(uuuuM128d a,_uuuM128dB){
返回(a),(b);;
}
cvtpd2dq xmm0,xmm0
cvtpd2dq xmm1,xmm1
punpcklqdq xmm0,xmm1#xmm0=xmm0[0],xmm1[0]
ret
//原著
__m128i封装到内部备份MMX(m128d a和m128d b){
返回设置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]
#请注意缺少EMM,因为它没有使用固有功能
ret

当SSE2和更高版本可用时,MMX几乎完全无用;只要避开它。有关一些指南,请参阅标记wiki。

Xcode没有对其进行优化。反汇编显示使用了cvtpd pi32,而set epi64只是使用mov来存储值。是的,它可以工作:mm_unpacklo_epi64(mm_cvtpd_epi32(v2dLo),mm_cvtpd_epi32(v2dHi))
#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