我进行了一个简单的实验,将if-else与if(默认值预设)进行比较。例如:
void test0(char c, int *x) {
*x = 0;
if (c == 99) {
*x = 15;
}
}
void test1(char c, int *x) {
if (c == 99) {
*x = 15;
} else {
*x = 0;
}
}
对于上面的函数,我得到了完全相同的汇编代码(使用cmovne
)。
但是在添加额外变量时:
void test2(char c, int *x, int *y) {
*x = 0;
*y = 0;
if (c == 99) {
*x = 15;
*y = 21;
}
}
void test3(char c, int *x, int *y) {
if (c == 99) {
*x = 15;
*y = 21;
} else {
*x = 0;
*y = 0;
}
}
组装突然变得不同了:
test2(char, int*, int*):
cmp dil, 99
mov DWORD PTR [rsi], 0
mov DWORD PTR [rdx], 0
je .L10
rep ret
.L10:
mov DWORD PTR [rsi], 15
mov DWORD PTR [rdx], 21
ret
test3(char, int*, int*):
cmp dil, 99
je .L14
mov DWORD PTR [rsi], 0
mov DWORD PTR [rdx], 0
ret
.L14:
mov DWORD PTR [rsi], 15
mov DWORD PTR [rdx], 21
ret
似乎唯一的区别是前mov
s是在je
之前或之后完成的。
现在(对不起,我的程序集有点粗糙),为了节省管道刷新,跳转后mov
s不总是更好吗?如果是这样,为什么优化器(gcc6.2 -O3)不会使用更好的方法?