C/C++优化离开检查以查看之前是否已运行过某个功能

ump*_*mps 18 c c++ optimization performance

假设您在C/C++中有一个函数,它在第一次运行时表现出某种特定的行为.然后,所有其他时间它表现出另一种方式(例如见下文).在第一次运行之后,if语句变得多余,如果速度很重要,可以将其优化掉.有没有办法进行这种优化?

bool val = true; 

void function1() {

   if (val == true) {
      // do something
      val = false; 
   }
   else {
      // do other stuff, val is never set to true again 
   }

}
Run Code Online (Sandbox Code Playgroud)

oua*_*uah 17

gcc 有一个内置函数,让您通知有关分支预测的实现:

 __builtin_expect 
Run Code Online (Sandbox Code Playgroud)

http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html

例如在你的情况下:

bool val = true; 

void function1()
{
    if (__builtin_expect(val, 0)) {
       // do something
       val = false; 
    }
    else {
      // do other stuff, val is never set to true again 
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 知道`__builtin_expect`很有用,但它在这里的效果可以忽略不计:在分支预测器"意识到"正在发生的事情之前,最多只有少数跳跃会被错误预测.当对两种结果中的一种产生偏见但没有可辨别的常规模式时,似乎会更有用. (2认同)

Luc*_*ore 16

如果您确定它确实是一个瓶颈,您应该只进行更改.使用分支预测,if语句可能是即时的,因为它是一种非常可预测的模式.

也就是说,你可以使用回调:

#include <iostream>
using namespace std;
typedef void (*FunPtr) (void);
FunPtr method;
void subsequentRun()
{
    std::cout << "subsequent call" << std::endl;
}
void firstRun()
{
    std::cout << "first run" << std::endl;
    method = subsequentRun;  
}
int main()
{
    method = firstRun;
    method();
    method();
    method();
}
Run Code Online (Sandbox Code Playgroud)

产生输出:

首先运行
后续呼叫
后续呼叫

  • 我想要确定这是否真的让事情变得更好或更糟.如果编译器现在必须将调用的目标视为未知,则由于无法在调用中应用优化,因此目标包含较少的分支可能会完全超过. (3认同)

Jac*_*ack 9

您可以使用函数指针,但在任何情况下都需要间接调用:

void (*yourFunction)(void) = &firstCall;

void firstCall() {
 ..
 yourFunction = &otherCalls;
}

void otherCalls() {
 ..
}

void main()
{
  yourFunction();
}
Run Code Online (Sandbox Code Playgroud)

  • 我不确定,但我怀疑这比原始代码慢. (2认同)