两部分我的问题。哪个更有效/更快:
int a,b,c,d,e,f;
int a1,b1,c1,d1,e1,f1;
int SumValue=0; // oops forgot zero
// ... define all values
SumValue=a*a1+b*b1+c*c1+d*d1+e*e1*f*f1;
或
Sumvalue+=a*a1+b*b1+c*c1;
Sumvalue+=d*d1+e*e1*f*f1;
我猜第一个是。我的第二个问题是为什么。
我想第三个问题是,在任何时候都需要分解一个加法运算(除了编译器对行连续数等的限制......)。
修改
当整个算术运算无法适应缓存时,我是唯一一次看到减速的时间吗?我认为这是不可能的 - 在这种情况发生之前,编译器可能会因为两次线路延续而感到生气。也许我明天要玩,看看。
答案 0 :(得分:5)
你有没有衡量?两种方法的优化机器代码可能非常相似,如果不相同的话。
编辑:我刚试过这个,结果就是我的预期:
$ gcc -O2 -S math1.c # your first approach
$ gcc -O2 -S math2.c # your second approach
$ diff -u math1.s math2.s
--- math1.s 2010-10-26 19:35:06.487021094 +0200
+++ math2.s 2010-10-26 19:35:08.918020954 +0200
@@ -1,4 +1,4 @@
- .file "math1.c"
+ .file "math2.c"
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "%d\n"
就是这样。相同的机器代码。
答案 1 :(得分:2)
你可以在一行上组合的操作数没有任意限制......实际上,编译器会接受你想要抛出的任何数字。编译器对操作的考虑发生在规定换行之后很久 - 它处理词法符号和语法规则,然后是抽象语法树。除非您的编译器编写得非常糟糕,否则这两个语句对int数据的执行效果都相同。
请注意,在result = a * b + c * d + e * f等中,编译器没有序列点并且知道优先级,因此可以完全自由地并行地评估和组合子表达式(给定有能力的硬件)。结果+ = a * b;结果+ = c * d;方法,你插入序列点,所以要求编译器在另一个之前完成一个表达式,但是可以自由地 - 并且应该 - 意识到结果不会在增量之间的其他地方使用,因此它可以像第一种情况一样自由优化
更一般地说:我可以为这些性能查询提供的最佳建议是1)不要担心它是一个实际问题,除非你的程序运行得太慢,然后分析找出哪里2)如果好奇或分析表明问题,然后尝试你能想到的两种/所有方法并测量实际表现。
除此之外:+ =有时可能更有效,例如:连接到现有字符串,因为这些对象上的+可能涉及创建临时和更多的内存分配 - 模板表达式解决这个问题但很少使用,因为它们实现起来非常复杂并且编译速度较慢。
答案 2 :(得分:1)
这就是熟悉汇编语言的原因。在这两种情况下,将生成汇编指令,将操作数对加载到寄存器中并执行加法/乘法,并将结果存储在寄存器中。根据您使用SumValue
SumValue.
所代表的内存地址中的说明
简而言之,两种结构都可能执行相同的操作,尤其是对于优化标记。即使他们不在某个平台上执行相同的操作,这两种方法都没有任何内在因素可以帮助解释为什么在C ++级别。通过查看编译器如何将C ++构造转换为汇编指令,您最多能够理解为什么一个表现优于另一个的原因。
我想第三个问题就是 点是否有必要打破 增加操作(除此之外) 编译器对行数的限制 延续等......)。
分解添加操作并不是必要。但它可能有助于提高可读性。
答案 3 :(得分:0)
它们最有可能被转换为相同数量的机器指令,因此它们需要相同的时间。