orl*_*rlp 5 c optimization sse compiler-optimization
使用SSE考虑这两个函数:
#include <xmmintrin.h>
int ftrunc1(float f) {
return _mm_cvttss_si32(_mm_set1_ps(f));
}
int ftrunc2(float f) {
return _mm_cvttss_si32(_mm_set_ss(f));
}
Run Code Online (Sandbox Code Playgroud)
对于任何输入,两者的行为完全相同.但是汇编器输出是不同的:
ftrunc1:
pushl %ebp
movl %esp, %ebp
cvttss2si 8(%ebp), %eax
leave
ret
ftrunc2:
pushl %ebp
movl %esp, %ebp
movss 8(%ebp), %xmm0
cvttss2si %xmm0, %eax
leave
ret
Run Code Online (Sandbox Code Playgroud)
也就是说,额外ftrunc2使用一条movss指令!
这是正常的吗?有关系吗?当你只需要设置底部元素时,应该_mm_set1_ps总是优先考虑_mm_set_ss吗?
使用的编译器是GCC 4.5.2 -O3 -msse.
_mm_set_ss直接映射到汇编指令(movss).但_mm_set1_ps事实并非如此.
从我在GCC,MSVC和ICC上看到的:
将一对一映射到汇编指令的SSE内在函数通常被视为"原样" - 黑盒子.因此编译器只会优化适用于整个指令本身.但它不会尝试进行任何需要对各个向量元素进行数据流/依赖性分析的优化.
在_mm_set1_ps和_mm_set_ps内在不映射到一个单一的指令,并有特殊的情况下,由大多数编译器处理.从我所看到的,我上面列出的所有三个编译器都尝试对各个元素执行数据流分析优化.
当你把它们放在一起时,第二个例子就离开了,movss因为编译器没有意识到前三个元素并不重要.(它没有试图"打开" _mm_set_ss内在的东西.)