Performance 什么';当前CPU的成本更高:算术运算还是条件运算?

Performance 什么';当前CPU的成本更高:算术运算还是条件运算?,performance,cpu,conditional-statements,arithmetic-expressions,Performance,Cpu,Conditional Statements,Arithmetic Expressions,20-30年前,除法等算术运算是CPU最昂贵的运算之一。在一段反复调用的代码中保存一个除法是一个显著的性能提升。但是今天CPU有快速的算术运算,并且由于它们大量使用,条件可能会破坏高效的执行。如果我想优化代码的速度,我应该更喜欢算术运算而不是条件运算吗 例1 假设我们想要实现模运算n。什么会表现更好: int c = a + b; result = (c >= n) ? (c - n) : c; int32_t x = ...; result = (x & 0x800000) ?

20-30年前,除法等算术运算是CPU最昂贵的运算之一。在一段反复调用的代码中保存一个除法是一个显著的性能提升。但是今天CPU有快速的算术运算,并且由于它们大量使用,条件可能会破坏高效的执行。如果我想优化代码的速度,我应该更喜欢算术运算而不是条件运算吗

例1 假设我们想要实现模运算
n
。什么会表现更好:

int c = a + b;
result = (c >= n) ? (c - n) : c;
int32_t x = ...;
result = (x & 0x800000) ? (x | 0xff000000) : x;

?

例2 假设我们正在将24位有符号数字转换为32位。什么会表现更好:

int c = a + b;
result = (c >= n) ? (c - n) : c;
int32_t x = ...;
result = (x & 0x800000) ? (x | 0xff000000) : x;

result=(x>8;

如果你想优化速度,你应该告诉你的编译器优化速度。现代编译器在这方面通常会比你做得更好

出于这个原因,我有时会惊讶地尝试将汇编代码与原始源代码联系起来


优化源代码的可读性,让编译器尽其所能。

编译器的作者和硬件开发者已经采摘并腌制了所有悬而未决的成果。如果你是那种需要问这样问题的人,你不太可能手工优化任何东西

20年前,一个相对有能力的程序员可以通过直接使用汇编来进行一些优化,而现在这是专门研究目标体系结构的专家的领域;此外,优化不仅需要知道程序,还需要知道它将处理的数据。一切都归结为启发式、测试和测试在不同的条件下等

简单的性能问题不再有简单的答案。

我希望在示例#1中,第一个问题的性能会更好。编译器可能会应用一些位旋转技巧来避免分支。但您正在利用编译器极不可能推断的知识:即总和始终在范围内e
[0:2*n-2]
所以一次减法就足够了


例如#2,第二种方法在现代CPU上速度更快,而且更易于遵循。明智的注释适用于任何一种版本。(如果编译器将第一个版本转换为第二个版本,我不会感到惊讶。)

他不是在这里写汇编。@BenVoigt:但我的答案是正确的。只适用于真正低级的东西。用较低复杂度替换算法仍然是一个非常理想的优化,编译器还不能为您完成。有条件有效的优化是程序员必须参与的另一个难点d、 无论是手动优化还是手动标记前提条件。@BenVoigt:是的,你是对的,但是根据问题的观点,这些点是不相关的。问题的答案是:“不可能知道,不知道确切的cpu,结果将被用于代码、编译器、月相等。”。即使是最简单的提升也会改变结果。只有在您没有信息的情况下,编译器才不会。许多优化仅对有限的输入范围有效。如果您知道约束得到满足,而编译器没有,则需要自己进行优化。编译器编写者有时不会花时间进行此类转换并非所有,只是因为它们不是通用的。对于“让编译器来处理它”的人群:我要求您找到一个编译器,它将生成相同的代码,例如给定的
int a=rand()%n,b=rand()%n;