这是一个愚蠢有趣的问题:
假设我们必须执行一个简单的操作,我们需要一半的变量值.有通常这样做的方法有两种:
y = x / 2.0;
// or...
y = x * 0.5;
Run Code Online (Sandbox Code Playgroud)
假设我们正在使用语言提供的标准运算符,哪一个具有更好的性能?
我猜测乘法通常更好,所以当我编码时我会坚持这一点,但我想证实这一点.
虽然我个人对Python 2.4-2.5 的答案感兴趣,但也可以发布其他语言的答案!如果您愿意,也可以随意发布其他更好的方式(比如使用按位移位运算符).
通过编码是否有任何(非微优化)性能增益
float f1 = 200f / 2
Run Code Online (Sandbox Code Playgroud)
在比较中
float f2 = 200f * 0.5
Run Code Online (Sandbox Code Playgroud)
几年前我的一位教授告诉我,浮点除法比浮点乘法慢,但没有详细说明原因.
这句话适用于现代PC架构吗?
UPDATE1
关于评论,请同时考虑这个案例:
float f1;
float f2 = 2
float f3 = 3;
for( i =0 ; i < 1e8; i++)
{
f1 = (i * f2 + i / f3) * 0.5; //or divide by 2.0f, respectively
}
Run Code Online (Sandbox Code Playgroud)
更新2 从评论中引用:
[我想]知道什么是算法/架构要求导致>除法在硬件上比复制要复杂得多
我很惊讶,(x & 255) == (x % 256)如果x是无符号整数,我想知道总是%用&in x % nfor 替换是否有意义,n = 2^a (a = [1, ...])而x是一个正整数.
因为这是一个特殊情况,我作为一个人可以决定,因为我知道程序将处理哪些值而编译器不会.如果我的程序使用了大量的模运算,我可以获得显着的性能提升吗?
当然,我可以编译并查看反汇编.但这只会回答我对一个编译器/架构的问题.我想知道这原则上是否更快.
我试图看看在我们的编辑中是否有写作之间的收益
x/3.0
Run Code Online (Sandbox Code Playgroud)
与const double one_over_three = 1.0/3.0; x*one_over_three;
但我需要一些帮助阅读装配,我还没有学到.
我编译了
int div3(double x) {
const double three = 1/3.0;
return x*three;
}
Run Code Online (Sandbox Code Playgroud)
并获得
div3(double):
pushq %rbp
movq %rsp, %rbp
movsd %xmm0, -24(%rbp)
movabsq $4599676419421066581, %rax
movq %rax, -8(%rbp)
movsd -24(%rbp), %xmm1
movsd .LC0(%rip), %xmm0
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
popq %rbp
ret
.LC0:
.long 1431655765
.long 1070945621
Run Code Online (Sandbox Code Playgroud)
然后编译
int div3(double x) {
return x/3.0;
}
Run Code Online (Sandbox Code Playgroud)
并获得
div3(double):
pushq %rbp
movq %rsp, %rbp
movsd %xmm0, -8(%rbp)
movsd -8(%rbp), %xmm0
movsd …Run Code Online (Sandbox Code Playgroud)