在下面的模板化函数示例中,for
循环内的中心 if
是否保证被优化掉,只留下使用的指令?
如果不能保证优化(在 GCC 4、MSVC 2013 和 llvm 8.0 中),有哪些替代方案(最多使用 C++11)?
注意,这个函数没有做任何有用的事情,而且我知道这个特定的函数可以通过多种方式进行优化等等。但我想关注的是 bool
模板参数在生成代码时如何工作。
template <bool IsMin>
float IterateOverArray(float* vals, int arraySize) {
float ret = (IsMin ? std::numeric_limits<float>::max() : -std::numeric_limits<float>::max());
for (int x = 0; x < arraySize; x++) {
// Is this code optimized by the compiler to skip the unnecessary if?
if (isMin) {
if (ret > vals[x]) ret = vals[x];
} else {
if (ret < vals[x]) ret = vals[x];
}
}
return val;
}
最佳答案
理论上没有。 C++ 标准不仅允许编译器愚蠢,而且还允许编译器完全敌对。只要抽象机器行为保持不变,它就可以无缘无故地注入(inject)代码做无用的事情。1
实际上,是的。死代码消除和常量分支检测很容易,我检查过的每个编译器都消除了 if
分支。
请注意,两个分支都是在删除一个分支之前编译的,因此它们都必须是完全有效的代码。输出程序集的行为“好像”两个分支都存在,但分支指令(和无法访问的代码)不是抽象机器行为的可观察特征。
当然,如果您不进行优化,分支和死代码可能会保留下来,因此您可以使用调试器将指令指针移动到“死代码”中。
<小时/>1 例如,没有什么可以阻止编译器将 a+b
实现为在汇编中调用 inc 的循环,或 a*b
作为循环重复添加a
。这是编译器在几乎所有平台上的敌对行为,但并未被标准禁止。
关于c++ - 带有模板 bool 参数的函数 : guaranteed to be optimized?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42228600/