【问题标题】:Optimization of inlined values内联值的优化
【发布时间】:2013-09-24 10:34:36
【问题描述】:

我有以下内联方法,并在其他方法中多次调用它。具有 O2 优化的 vc 和 gcc 编译器是否能够注意到该值在调用方法中是固定的并且只评估一次? -- 实际上indexAndFlag 在这些方法中没有改变。 -- 或者,也许为了线程安全,每次调用都会对其进行评估?

unsigned int indexAndFlag;
...

inline Index* index() const
{
    return (Index*)(indexAndFlag & ~1);
}

代码仅适用于保护模式 x86 32/64 位架构,所以我希望,我可以假设 sizeof(unsigned int) == sizeof(Index*)。如果不是,请纠正我。

【问题讨论】:

  • 最好检查一下。 objdump -d ...
  • 我不知道 x86/64 的保护模式是什么,但你可以断言大小是否相同

标签: c++ visual-c++ optimization gcc inline


【解决方案1】:

如果看起来indexAndFlag 是一个非常量非静态全局变量,那么不是。编译器无法确定另一个翻译单元是否可以修改它,因此程序必须在任何地方访问它的值。

如果它是const,并使用常量表达式初始化,那么编译器必须将其视为常量值,并且您的表达式应该也被视为常量值。

我希望,我可以假设sizeof(unsigned int) == sizeof(Index*)

我不会:许多流行的 64 位架构都有 32 位 int。请务必使用uintptr_t

【讨论】:

  • 谢谢。但是indexAndFlag & ~1 是否适合uintptr_t indexAndFlag?在 32bit int 和 64 指针的情况下不会有 32 个 0 吗?
  • @Number47:是的,你也应该使用~uintptr_t(1)。或~mask,声明const uintptr_t mask = 1;
【解决方案2】:

从底部开始:sizeof(unsigned int) != sizeof(Index *) 64 位,这是肯定的。如果您做出这样的假设,我肯定会建议您在代码中的某处使用static_assert(sizeof(unsigned int) == sizeof(Index *))

接下来,编译器在全局变量和优化方面做什么或不做什么肯定是“由编译器决定”的情况。编译器可能会决定每次都重新加载该值,或者它可能会决定“啊,我知道这不会改变”。这实际上取决于它“理解”indexAndFlag 没有改变的程度。

我个人会使用类似的东西:

 Index* temp = index();

  ... 
   use temp
  ...

那么就保证不会进行额外的操作来“计算”索引。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-18
    • 1970-01-01
    • 2011-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-10
    • 2011-12-23
    相关资源
    最近更新 更多