相关疑难解决方法(0)

如何在没有运行时成本的情况下基于断言来指导GCC优化?

我有一个宏在我的代码中使用,在调试模式下:

#define contract(condition) \
    if (!(condition)) \
        throw exception("a contract has been violated");
Run Code Online (Sandbox Code Playgroud)

...但在发布模式下:

#define contract(condition) \
    if (!(condition)) \
        __builtin_unreachable();
Run Code Online (Sandbox Code Playgroud)

这样做的原因assert()是,在发布版本中,由于UB传播,编译器可以大量优化代码.

例如,使用以下代码进行测试:

int foo(int i) {
    contract(i == 1);
    return i;
}

// ...

foo(0);
Run Code Online (Sandbox Code Playgroud)

...在调试模式下抛出异常,但return 1;在释放模式下为无条件生成程序集:

foo(int):
        mov     eax, 1
        ret
Run Code Online (Sandbox Code Playgroud)

条件以及依赖它的一切都已经过优化.

我的问题出现在更复杂的条件下.当编译器无法证明条件没有副作用时,它不会将其优化出来,与不使用合同相比,这是一个严重的惩罚.

有没有办法表明合同中的条件没有副作用,所以总是优化出来?

c++ optimization gcc assert compiler-optimization

22
推荐指数
3
解决办法
1104
查看次数

优化,断言和释放模式

考虑一个功能

void f() {
   assert(condition);

   ...
}
Run Code Online (Sandbox Code Playgroud)

在调试模式下,如果启用了断言,则编译器可以自由地假设condition保持,因为如果没有,则不会执行剩余的代码.

但是,在发布模式下,我相信编译器只会看到

void f() {
   ...
}
Run Code Online (Sandbox Code Playgroud)

而且不能再假设了condition.

是否有任何编译器指令或静态断言技巧让编译器了解某些不变量?

c c++ optimization assert static-assert

7
推荐指数
1
解决办法
2090
查看次数

是否有任何理由不将assert() 包装在解析为gcc 中的__builtin_unreachable() 的宏中?

上下文:在这个答案中,我了解到 gcc__builtin_unreachable()可能会对性能产生一些令人惊讶的影响,因为看起来如下:

if(condition) __builtin_unreachable();
Run Code Online (Sandbox Code Playgroud)

被完全剥离,只要condition能保证没有任何副作用,就可以用作优化提示。

因此,我对此的立即反应是,我应该创建以下宏,并在我通常使用的任何地方都使用它assert(),因为在 an 内诱导代码的副作用assert()首先将是一个主要错误:

// TODO: add handling of other compilers as appropriate.
#if defined(__GNUC__) && defined(NDEBUG)
  #define my_assert(condition) \
    if(!(condition)) __builtin_unreachable()
#else 
  #define my_assert(condition) assert(condition)
#endif
Run Code Online (Sandbox Code Playgroud)

从标准的角度来看,这将在正常和构建之间创建功能划分NDEBUG,您可以提出一个论据,将该宏排除在assert(). 然而,由于无论如何,在断言失败的情况下,我的代码在功能上都会死在水中,因此从行为的角度来看,它是完全等效的。

所以我的问题是:任何人都可以想出一个不这样做的理由(除了涉及大量间接的断言之外)?

在你问之前,是的,我已经检查过 gcc 的行为是在构建中无效地放弃断言NDEBUG

c++ optimization gcc assert

5
推荐指数
1
解决办法
724
查看次数