【问题标题】:C++: pow() optimizations with two constantsC++:具有两个常量的 pow() 优化
【发布时间】:2012-02-12 12:38:31
【问题描述】:

简单的问题:当编译器面临对 pow() 的调用时,例如,使用 两个常量(即来自宏的值)(即来自宏的值),它是通过在编译时评估它来优化它,还是它仍然是在运行时计算?

例子:

#define V_BITMEM_GRID 3
#define V_BITMEM_TOTAL pow(V_BITMEM_GRID,2)

谢谢!

编辑如果没有,有没有办法在编译时将宏的平方/立方体计算为另一个宏(就像我在上面尝试的那样)?

【问题讨论】:

  • 这将取决于编译器。你可以看看你的编译器生成的汇编代码。
  • 如果您的编译器的优化器不在运行时评估 pow,模板元编程就可以完成这项工作
  • @DavidHeffernan - 模板元编程?我得调查一下。这些宏在多个循环中使用,对 pow() 的调用会非常费劲。
  • 如果您只对常量的平方/立方感兴趣,我相信几乎所有编译器都会在编译时评估类似的内容:#define V_BITMEM_GRID 3#define V_BITMEM_TOTAL V_BITMEM_GRID * V_BITMEM_GRID。在这种情况下,没有函数调用,而是一个具有常量值的简单数学运算符。

标签: c++ optimization pow


【解决方案1】:

两者都可以。这取决于编译器的侵入性,它是否可以访问函数实现并可以正确评估它。只要观察到的行为相同,就没有规则规定它应该如何。

例如,我得到了以下内容:

#define X 1
#define Y 2
int foo(int x, int y)
{
    return x + y;
}

int main(int argc, char* argv[])
{
    cout << foo(X,Y);
00BE1000  mov         ecx,dword ptr [__imp_std::cout (0BE203Ch)] 
00BE1006  push        3    
00BE1008  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0BE2038h)] 
}

如您所见,该函数甚至没有被调用。所以这个电话有可能被永远消除了。

【讨论】:

  • 这很好地回答了我的问题。我将不得不玩弄 vs2008 来弄清楚如何获得输出,但我根本没想过这样做!
  • @Di-0xide 在调试时,右键单击并选择“显示分解”
【解决方案2】:

你不应该依赖它。基于宏的方法是:

#define POW1(x) (x)
#define POW2(x) ((x)*(x))
#define POW3(x) (POW2(x)*POW1(x))
...
#define POW(x, y) POW##y(x)

【讨论】:

  • 如果 x 不是一个常量表达式,这可能比优化的积分幂函数差得多
【解决方案3】:

gcc 在编译时计算此类表达式,例如

【讨论】:

  • 也许您的答案缺少最后一部分? ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-16
  • 2011-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多