包含许多"if"的临界循环,其输出是常量:如何保存条件测试?

Nat*_*hen 4 c c++ optimization gcc g++

我的代码中有一个关键循环,具有以下形状:

int myloop(int a, .....){

   /* some stuff */

   // Critical loop
   while(...){
       /* Some Stuff */
       if(a == 1){
          // .....
       }
       else if(a == 2){
          // .....
       }
       else if(a == 3){
          // .....
       }
       else{
          // ....
       }
   }
}
Run Code Online (Sandbox Code Playgroud)

由于循环从不接触"a"的值,所采用的分支永远不会改变,但由于此循环非常重,因此需要多次测试"a"的值,这是完全没必要的.最好的事情可能是复制循环,以便在循环开始之前可以测试"if",但这意味着复制了两种情况共同的许多东西,并且会导致非常难看的代码......

有没有办法要求GCC/G ++在编译时复制这段代码?或者任何其他技巧,以避免这么多次测试价值?

谢谢您的帮助 !

Nathann

Ale*_*ler 6

首先,您可以switch在此处使用声明:

switch(a) {

   case 0:
     // handle a==0
     break;

   case 1:
     // handle a==1
     break;

   default:
     // handle all other cases
}
Run Code Online (Sandbox Code Playgroud)

可以使编译器生成更快的代码,即执行单个计算跳转而不是多次检查a.

这意味着要复制两种情况共同的许多东西

重构!如何将共享代码放入一个单独的函数中,可能会声明它inline,并希望编译器遵循提示?函数内联是让编译器执行代码复制的好方法(另外两种方式是模板和预处理器,这两种方式在这里显然都不合适).

inline void sharedStuff() {...}

int myloop(int a, .....){

   /* some stuff */

   if (a==1) {

      while(...){

         // code specific to a==1

         // do shared stuff
         sharedStuff();
      }

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

当然这取决于你在循环中做了什么,但你应该得到基本原则.

最后但并非最不重要的:轮廓.检查循环是否真的是性能瓶颈.看看生成的机器代码.很可能编译器已经使用了大多数提议的优化.