首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >历史上推荐使用的x86中哪些类型的C优化实践不再有效?

历史上推荐使用的x86中哪些类型的C优化实践不再有效?
EN

Stack Overflow用户
提问于 2014-06-05 20:24:19
回答 4查看 1.1K关注 0票数 29

由于x86 C编译器(即GCC和Clang)的进步,许多被认为能提高效率的编码实践不再使用,因为编译器可以比人类(例如bit shift vs. multiplication)更好地优化代码。

这些具体做法是什么?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-06-05 20:57:55

在通常推荐的优化中,对于现代编译器来说,一些基本上从未取得成果的优化包括:

数学变换

现代编译器理解数学,并在适当的情况下对数学表达式进行转换。

优化,如乘法转换为加法,或常量乘法或除法为位移位,已经由现代编译器执行,即使在低优化水平。这些优化的例子包括:

代码语言:javascript
复制
x * 2  ->  x + x
x * 2  ->  x << 1

请注意,某些具体情况可能有所不同。例如,x >> 1x / 2不一样;用一个代替另一个是不合适的!

此外,这些建议中的许多优化实际上并不比它们替换的代码更快。

愚蠢的代码技巧

我甚至不知道如何称呼它,但是像XOR交换(a ^= b; b ^= a; a ^= b;)这样的技巧根本不是优化。它们只是聚会的花招--它们比显而易见的方法要慢一些,也更脆弱。别用它们。

register关键字

这个关键字被许多现代编译器忽略,因为它的意图(强制变量存储在寄存器中)在当前的寄存器分配算法中是没有意义的。

代码转换

编译器将在适当情况下自动执行各种各样的代码转换。经常推荐用于手动应用的几种此类转换(但在应用时很少有用)包括:

  • 循环展开.(当不加区分地应用时,这通常是有害的,因为它会膨胀代码大小)。
  • 函数内联。(将函数标记为static,在启用优化时通常会在适当的地方内联)。
票数 18
EN

Stack Overflow用户

发布于 2014-06-05 20:56:58

其中一种做法是使用数组指针数组来避免乘法,而不是使用真正的2D数组。

旧习俗:

代码语言:javascript
复制
int width = 1234, height = 5678;
int* buffer = malloc(width*height*sizeof(*buffer));
int** image = malloc(height*sizeof(*image));
for(int i = height; i--; ) image[i] = &buffer[i*width];

//Now do some heavy computations with image[y][x].

这曾经更快,因为乘法过去非常昂贵(大约30个CPU周期),而内存访问实际上是免费的(直到20世纪90年代才增加缓存,因为内存无法跟上整个CPU的速度)。

但是乘法变得很快,一些CPU能够在一个CPU周期内完成它们,而内存访问却根本跟不上进度。因此,现在这段代码可能具有更强的性能:

代码语言:javascript
复制
int width = 1234, height = 5678;
int (*image)[width] = malloc(height*sizeof(*image));

//Now do some heavy computations with image[y][x],
//which will invoke pointer arithmetic to calculate the offset as (y*width + x)*sizeof(int).

目前,仍然有一些CPU,在那里的第二个代码不是更快,但大的乘法惩罚不再与我们在一起。

票数 8
EN

Stack Overflow用户

发布于 2014-06-05 21:02:29

由于平台的多样性,您最多可以对给定平台(或CPU体系结构/模型)和编译器进行优化!!如果您的代码在许多平台上运行,这是浪费时间。(我说的是微选择,它总是值得考虑更好的算法)

这就是说对给定的平台进行优化,如果需要的话DSP是有意义的。那么最好的第一个助手是IMHO,如果编译器/优化器很好地支持它,那么明智地使用restrict关键字。避免涉及条件和跳变代码的算法(中断、goto、如果、时间、.)这有利于流,并避免了太多糟糕的分支预测。我同意这些暗示现在是常识。

一般说来,我想说的是:任何通过假设编译器如何优化来修改代码的操作都应该避免.

相反,切换到程序集(对于DSP中一些非常重要的算法来说,通常的做法是编译器虽然非常优秀,但仍然忽略了CPU/Mem周期的最后几%的性能提高……)

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24069608

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档