5

20-30 年前,除法等算术运算是 CPU 成本最高的运算之一。在一段重复调用的代码中保存一个部门是显着的性能提升。但是今天的 CPU 具有快速的算术运算,并且由于它们大量使用指令流水线,因此条件会破坏有效的执行。如果我想优化代码以提高速度,我应该更喜欢算术运算而不是条件吗?

示例 1

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

int c = a + b;
result = (c >= n) ? (c - n) : c;

或者

result = (a + b) % n;

?

示例 2

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

int32_t x = ...;
result = (x & 0x800000) ? (x | 0xff000000) : x;

或者

result = (x << 8) >> 8;

?

4

3 回答 3

2

如果你想优化速度,你应该告诉你的编译器优化速度。现代编译器通常会在这方面胜过您。

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

优化源代码的可读性,让编译器做它最擅长的事情。

于 2013-02-09T15:53:16.787 回答
2

编译器的作者和构建硬件的人已经挑选和腌制了所有低调的果实。如果你是那种需要问这样的问题的人,你不可能手动优化任何东西。

虽然在 20 年前,相对称职的程序员可以通过下降到汇编来进行一些优化,但现在它是专家的领域,专门研究目标架构;此外,优化不仅需要了解程序,还需要了解它将处理的数据。一切都归结为启发式、不同条件下的测试等。

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

于 2013-02-09T16:06:50.520 回答
2

我希望在示例 #1 中,第一个会表现得更好。编译器可能会应用一些小技巧来避免分支。但是您正在利用编译器极不可能推断出的知识:即总和始终在范围内[0:2*n-2],因此一个减法就足够了。

例如#2,第二种方式在现代 CPU 上速度更快,而且更易于遵循。在任何一个版本中,明智的评论都是合适的。(看到编译器将第一个版本转换为第二个版本,我不会感到惊讶。)

于 2013-02-09T16:36:33.977 回答