最近我在我的CS研究中得到了一个代码示例(参见代码#1),并且如果我的第二版代码更快或使用更少的内存,我会尝试引出。 你对我的问题有答案吗?
// Code #1
double f(double b, double x)
{
double s;
if (x == 0.0)
s = 1.0;
else
s = sin(x)/x;
return s + b;
}
// Code #2
double f(double b, double x)
{
// I thought this would be faster and using less memory due to
// not declaring a new double
if (x == 0.0)
return 1.0 + b;
else
return sin(x)/x + b;
}
谢谢你们的帮助。
答案 0 :(得分:1)
这取决于编译器和优化标志。一般来说,两个代码都会给出相同的结果。
答案 1 :(得分:1)
我已经生成了这两种情况的汇编。
案例1:
push rbp
mov rbp, rsp
sub rsp, 48
movsd QWORD PTR [rbp-24], xmm0
movsd QWORD PTR [rbp-32], xmm1
pxor xmm0, xmm0
ucomisd xmm0, QWORD PTR [rbp-32]
jp .L2
pxor xmm0, xmm0
ucomisd xmm0, QWORD PTR [rbp-32]
jne .L2
movsd xmm0, QWORD PTR .LC1[rip]
movsd QWORD PTR [rbp-8], xmm0
jmp .L4
.L2:
mov rax, QWORD PTR [rbp-32]
mov QWORD PTR [rbp-40], rax
movsd xmm0, QWORD PTR [rbp-40]
call sin
divsd xmm0, QWORD PTR [rbp-32]
movsd QWORD PTR [rbp-8], xmm0
.L4:
movsd xmm0, QWORD PTR [rbp-8]
addsd xmm0, QWORD PTR [rbp-24]
leave
ret
.LC1:
.long 0
.long 1072693248
案例2:
push rbp
mov rbp, rsp
sub rsp, 32
movsd QWORD PTR [rbp-8], xmm0
movsd QWORD PTR [rbp-16], xmm1
pxor xmm0, xmm0
ucomisd xmm0, QWORD PTR [rbp-16]
jp .L2
pxor xmm0, xmm0
ucomisd xmm0, QWORD PTR [rbp-16]
jne .L2
movsd xmm1, QWORD PTR [rbp-8]
movsd xmm0, QWORD PTR .LC1[rip]
addsd xmm0, xmm1
jmp .L4
.L2:
mov rax, QWORD PTR [rbp-16]
mov QWORD PTR [rbp-24], rax
movsd xmm0, QWORD PTR [rbp-24]
call sin
divsd xmm0, QWORD PTR [rbp-16]
addsd xmm0, QWORD PTR [rbp-8]
.L4:
leave
ret
.LC1:
.long 0
.long 1072693248
没有区别。因此,它们之间没有速度优化。因此,代码优化依赖于编译器。
答案 2 :(得分:1)
只声明变量不仅仅是占用记忆的东西。
int a = 1 + 2;
int b = 3;
int c = a + b;
此代码将采用与以下代码相同的值
int c = 1 + 2 + 3;
因为最终处理器将在单核中一次执行一个操作 第二个代码添加两个数字并将其保存在堆栈中,然后取第三个数字添加前两个数字的结果。
答案 3 :(得分:1)
简短回答:别担心!
答案很长:
sin
将占用此功能的最多时间,因此一些额外的指令(如果有的话)将不会产生任何明显的影响。
虽然有疑问,look生成的代码。
在x86_64上使用GCC 6.3,第一个版本使用1个寄存器(xmm2),但优化器能够更好地重新排序指令。
版本1:
ucomisd xmm1, QWORD PTR .LC1[rip]
movapd xmm2, xmm0
jp .L5
movsd xmm0, QWORD PTR .LC0[rip]
je .L7
.L5:
movapd xmm0, xmm1
sub rsp, 24
movsd QWORD PTR [rsp+8], xmm2
movsd QWORD PTR [rsp], xmm1
call sin
movsd xmm1, QWORD PTR [rsp]
movsd xmm2, QWORD PTR [rsp+8]
add rsp, 24
divsd xmm0, xmm1
addsd xmm0, xmm2
ret
.L7:
addsd xmm0, xmm2
ret
第2版:
ucomisd xmm1, QWORD PTR .LC0[rip]
jp .L2
je .L10
.L2:
sub rsp, 24
movsd QWORD PTR [rsp], xmm0
movapd xmm0, xmm1
movsd QWORD PTR [rsp+8], xmm1
call sin
movsd xmm1, QWORD PTR [rsp+8]
divsd xmm0, xmm1
addsd xmm0, QWORD PTR [rsp]
add rsp, 24
ret
.L10:
addsd xmm0, QWORD PTR .LC1[rip]
ret
那么这两个版本之间的性能差异有多大?只有性能测试才能确定(但我的猜测是你赢了但没有看到任何区别)。