【发布时间】:2013-12-25 09:48:06
【问题描述】:
我认为一个比较必须比两个快。但是经过我的测试,我发现在调试模式下短比较快一点,而在发布模式下,字符比较更快。我想知道真正的原因。
以下是测试代码和测试结果。我写了两个简单的函数,func1() 使用两个字符比较,func2() 使用一个短比较。主函数返回临时返回值以避免编译优化忽略我的测试代码。我的编译器是 GCC 4.7.2,CPU Intel® Xeon® CPU E5-2430 0 @ 2.20GHz (VM)。
inline int func1(unsigned char word[2])
{
if (word[0] == 0xff && word[1] == 0xff)
return 1;
return 0;
}
inline int func2(unsigned char word[2])
{
if (*(unsigned short*)word == 0xffff)
return 1;
return 0;
}
int main()
{
int n_ret = 0;
for (int j = 0; j < 10000; ++j)
for (int i = 0; i < 70000; ++i)
n_ret += func2((unsigned char*)&i);
return n_ret;
}
调试模式:
func1 func2
real 0m3.621s 0m3.586s
user 0m3.614s 0m3.579s
sys 0m0.001s 0m0.000s
发布模式:
func1 func2
real 0m0.833s 0m0.880s
user 0m0.831s 0m0.878s
sys 0m0.000s 0m0.002s
func1版的汇编代码:
.cfi_startproc
movl $10000, %esi
xorl %eax, %eax
.p2align 4,,10
.p2align 3
.L6:
movl $1, %edx
xorl %ecx, %ecx
.p2align 4,,10
.p2align 3
.L8:
movl %edx, -24(%rsp)
addl $1, %edx
addl %ecx, %eax
cmpl $70001, %edx
je .L3
xorl %ecx, %ecx
cmpb $-1, -24(%rsp)
jne .L8
xorl %ecx, %ecx
cmpb $-1, -23(%rsp)
sete %cl
jmp .L8
.p2align 4,,10
.p2align 3
.L3:
subl $1, %esi
jne .L6
rep
ret
.cfi_endproc
func2版的汇编代码:
.cfi_startproc
movl $10000, %esi
xorl %eax, %eax
.p2align 4,,10
.p2align 3
.L4:
movl $1, %edx
xorl %ecx, %ecx
jmp .L3
.p2align 4,,10
.p2align 3
.L7:
movzwl -24(%rsp), %ecx
.L3:
cmpw $-1, %cx
movl %edx, -24(%rsp)
sete %cl
addl $1, %edx
movzbl %cl, %ecx
addl %ecx, %eax
cmpl $70001, %edx
jne .L7
subl $1, %esi
jne .L4
rep
ret
.cfi_endproc
【问题讨论】:
-
1) 是否一直更快?或者这只是一个小故障? 2) 向我们展示生成的汇编代码。
-
嗯...那些时间远远超出了测量的不确定性...此外,调试构建(==没有优化)没有有意义的时间/复杂性配置文件。此外,第二个函数调用了未定义的行为,因此甚至不值得推理。
-
您必须展示编译器在每种情况下生成的汇编代码,才能使对该主题的任何讨论有意义。 C 代码没有内在性能。 (从技术上讲,汇编代码也不能没有目标处理器,但我们假设一个现代的广泛可用的处理器)
-
这些数字几乎相同。一次关闭会受到操作系统切换等的影响。至少运行几百次。
-
@PascalCuoq 事实并非如此,因为
&i是int *。
标签: c++ c performance assembly