Thr*_*r57 3 x86 sse intrinsics micro-optimization sse3
如果我的理解是正确的,
_mm_movehdup_ps(a) 
给出与以下结果相同的结果
_mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 3, 3))?
两者在性能上有区别吗?
_MM_SHUFFLE首先需要较高的元素,所以_MM_SHUFFLE(3,3, 1,1)会进行movshdup随机播放。
主要区别在于装配级别;movshdup是一个复制和混洗,movaps如果a以后仍需要输入,则避免使用a 复制输入(例如,作为水平和的一部分:请参见在x86上进行水平浮点矢量和的最快方法,以获取如何在不使用a的情况下进行编译的示例)movaps与使用的SSE1版本shufps。
movshdup/ movsldup也可以是带有内存源操作数的load + shuffle。(shufps显然不能,因为它需要两次相同的输入。)在现代Intel CPU(Sandybridge系列)上,movshdup xmm0, [rdi]解码为纯负载uop,而不是与ALU uop微融合。因此,它无法与其他洗牌竞争ALU洗牌吞吐量(端口5)。加载端口包含用于执行广播加载(包括movddup64位广播)和movs[lh]dup元素对复制的逻辑。更复杂的load + shuffle 仍然会解码为多个微码,vpermilps xmm0, [rdi], 0x12或者pshufd xmm, [rdi], 0x12根据uarch可能微融合为load + ALU。
两条指令的长度相同:movshdup避免使用立即数字节,而是shufps一条SSE1指令,因此它只有2字节的操作码,比SSE2和SSE3指令短1个字节。  但是启用AVX后,vmovshdup确实会节省一个字节,因为操作码大小的优势已消失。
在只有64位洗牌单元的较旧CPU(如奔腾M和第一代Core 2(Merom))上,性能优势更大。  movshdup仅在向量的64位一半内随机播放。在Core 2 Merom上,movshdup xmm, xmm解码为1 uop,但shufps xmm, xmm, i解码为3 uops。(请参阅https://agner.org/optimize/了解指令表和Microarch指南)。另请参阅我的水平总和答案(先前链接),以了解有关诸如Merom和K8之类的SlowShuffle CPU的更多信息。
如果启用了SSE3,则如果您的编译器未将其优化_mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 3, 1, 1))为与之相同的程序集,则这是错过的优化_mm_movehdup_ps(a)。
不过,有些编译器(例如MSVC)通常不会优化内部函数,因此,程序员应了解movaps通过使用内在函数进行复制和混洗指令(例如pshufd和movshdup)来避免避免指令的asm含义,而不是通过混洗来破坏它们的本质目标寄存器(如shufps和psrldq字节移位一样。)
同样,MSVC不允许您启用编译器对SSE3的使用,如果对它们使用内在函数,则仅会获得超出基线SSE2(或没有SIMD)的指令。或者,如果启用了AVX,则允许编译器也使用SSE4.2和更早版本,但仍选择不进行优化。如此一来,由人工程序员来寻找优化。ICC与此类似。如果您确切地知道自己在做什么并且正在检查编译器的asm输出,则有时这可能是一件好事,因为有时gcc或clang的优化可能会使您的代码悲观。
用clang编译并查看它是否使用与源代码中的内在函数相同的指令可能是一个好主意;在支持Intel内在函数的4个主要编译器中,它是迄今为止最好的改组优化器,基本上以与编译器通常优化纯C的方式相同的方式(即仅遵循as-if规则产生相同的结果)优化内在代码。
最简单的例子:
#include <immintrin.h>
__m128 shuf1(__m128 a) {
    return _mm_shuffle_ps(a,a, _MM_SHUFFLE(3,3, 1,1));
}
在Godbolt上用gcc / clang / MSVC / ICC编译
GCC和clang -O3 -march=core2都可以发现优化:
shuf1:
        movshdup        xmm0, xmm0
        ret
ICC -O3 -march=haswell和MSVC -O2 -arch:AVX -Gv(启用向量调用调用约定,而不是通过引用传递SIMD向量。)
shuf1:
        vshufps   xmm0, xmm0, xmm0, 245                         #4.12
        ret                                                     #4.12
| 归档时间: | 
 | 
| 查看次数: | 96 次 | 
| 最近记录: |