Par*_*e56 9 c c++ optimization gcc loops
我正在使用GCC编译器测试C/C++中的各种优化.我目前有一个包含多个嵌套if语句的循环.条件是在程序执行开始时计算的.看起来有点像这样:
bool conditionA = getA();
bool conditionB = getB();
bool conditionC = getC();
//Etc.
startTiming();
do {
if(conditionA) {
doATrueStuff();
if(conditionB) {
//Etc.
} else {
//Etc.
}
} else {
doAFalseStuff();
if(conditionB) {
//Etc.
} else {
//Etc.
}
}
} while (testCondition());
endTiming();
Run Code Online (Sandbox Code Playgroud)
doATrueStuff()内联函数在哪里进行一些简单的数值计算,因此调用它没有任何开销.
不幸的是,不能事先定义条件,它们必须在运行时计算.我们甚至无法可靠地预测他们是真是假的可能性.getA()也许是rand()%2.但经过计算,它们的价值永远不会改变.
我想到了两个解决方案,一个是全局函数指针,用于在循环中调用适当的函数,如下所示:
void (*ptrA)(void);
//Etc.
int main(int argc, char **argv) {
//...
if (conditionA) {
ptrA=&aTrueFunc;
} else {
ptrA=&aFalseFunc;
}
//...
do {
(*ptrA)();
} while (testCondition());
//...
}
Run Code Online (Sandbox Code Playgroud)
这样我可以从循环中消除所有分支,但是然后我将有多个函数调用的开销减慢我的速度.
或者我可以简单地为每个条件组合设置一个不同的循环,如下所示:
if(conditionA) {
if(conditionB) {
do {
//Do A == true B == true stuff
} while (testCondition());
} else {
do {
//Do A == true B == false stuff
} while (testCondition());
}
} else {
//Etc.
}
Run Code Online (Sandbox Code Playgroud)
然而,当一个人开始拥有太多条件时,这样就不那么优雅并且不可能有效地做到这一点,因为对于X条件,人们需要编写2 ^ X个循环.
是否有更优雅/更快的方式来优化它?
在这方面是否有任何意义,或者编译器是否会以某种方式理解条件在循环期间不会发生变化并自行优化?
出于好奇,有没有其他编程语言可以使编写这样的代码更容易/可能?或者只有通过使用程序集在程序加载到内存后更改程序的指令才能实现?
理论:
尝试通过一些古怪的重写来优化代码可能会使编译器难以进行通常的优化。编译器和处理器可以使用两种技术来优化代码:
作为一个简单的开发人员,使用 gcc,您还可以使用“可能”和“不太可能”编译提示来帮助分支预测或代码生成。点击此处了解更多详情。例如,如果您知道一种情况比另一种情况更有可能发生,那么这可能会起作用。
要查看分支预测效率,请使用perf stat ./binary并检查分支未命中率以及您执行的每次优化的分支未命中数。
在您的代码案例中:
如果条件A、条件B和条件C在循环之前计算并且不改变,则分支预测器很容易检测到该模式。CPU 的预测器通过跟踪最后采用/未采用的分支来实现这一点,并将使用记录的历史记录来预测后续分支。因此,我实际上预计由于代码中的分支而导致的性能损失非常小,您可以按照上面的方法进行验证。
| 归档时间: |
|
| 查看次数: |
2578 次 |
| 最近记录: |