20

当我阅读 C 中的技巧时,我在这里看到了这个技巧http://www.cprogramming.com/tips/tip/multiply-rather-than-divide 但我不确定。有人告诉我,乘法和除法都较慢且耗时,并且需要很多周期。

而且我看到人们经常使用i << 2而不是i x 4因为换档更快。

使用它是一个很好的提示x0.5 or /2吗?还是现代编译器确实以更好的方式对其进行了优化?

4

5 回答 5

26

确实,某些(如果不是大多数)处理器的倍增速度比执行除法运算要快,但是,这就像++ii++for 循环更快的神话。是的,它曾经是,但现在,编译器足够聪明,可以为你优化所有这些东西,所以你不应该再关心这个了。

关于移位,曾经移位<< 2比乘以 4 更快,但那些日子已经结束,因为大多数处理器可以在一个时钟周期内进行乘法运算,就像移位操作一样。

一个很好的例子是在 VGA320x240模式下计算像素地址。他们都这样做了:

address = x + (y << 8) + (y << 6)

将 y 乘以 320。在现代处理器上,这可能比仅执行以下操作要慢:

address = x + y * 320;

所以,只要写下你的想法,编译器会做剩下的:)

于 2013-08-10T18:32:19.340 回答
16

我发现这项服务对于测试这类东西非常宝贵:

http://gcc.godbolt.org/

看看最后的组装。99% 的情况下,您会看到编译器将其全部优化为相同的代码。不要浪费脑力!

在某些情况下,最好明确地编写它。例如,2^n(其中 n 是一个正整数)可以写成,(int) pow( 2.0, n )但显然更好用1<<n(并且编译器不会为您进行优化)。因此,将这些事情留在您的脑海中是值得的。与任何事情一样,不要过早优化。

于 2013-08-10T18:33:19.180 回答
2
  1. “乘以 0.5 而不是除以 2”(2.0)现在在更少的环境中比以前更快,这主要是由于改进的编译器可以优化代码。

  2. 出于类似的原因,“使用 i << 2 而不是 ix 4”在较少的环境中更快。

  3. 某些情况下,程序员仍然需要处理此类问题,但这种情况越来越少。代码维护作为一个主要问题继续增长。因此,请使用对该代码片段最有意义的内容:x*0.5x/2.0half(x)等。

  4. 编译器很容易优化代码。建议您在编写代码时考虑到高级问题。例如。算法是 O(n) 还是 O(n*n)?

  5. 要传递的重要思想是最佳代码设计实践不断发展,环境之间会发生变化。适应性强。今天最好的东西可能会在未来发生变化(或成倍增加)。

于 2013-08-10T22:15:08.173 回答
1

许多 CPU 可以在 1 或 2 个时钟周期内执行乘法,但除法总是需要更长的时间(尽管 FP 除法有时比整数除法更快)。

如果您查看此答案,如何比较 C++ 中 log() 和 fp 除法的性能?您会看到除法可以超过 24 个周期。

为什么除法比乘法花这么多时间?如果您还记得小学时,您可能还记得乘法基本上可以通过许多同时加法来执行。除法需要迭代减法,不能同时执行,因此需要更长的时间。事实上,一些 FP 单元通过执行倒数近似并乘以它来加速除法。它不太准确,但速度更快。

于 2013-08-10T18:34:05.917 回答
1

如果您正在使用整数,并且您希望得到一个整数作为结果,最好使用/ 2,这样可以避免不必要的与浮点数的转换

于 2013-08-10T18:35:45.733 回答