C++ 使用函数指针剪切if语句是否会更有效?
因此,有一条规则试图将C++ 使用函数指针剪切if语句是否会更有效?,c++,performance,function-pointers,data-oriented-design,C++,Performance,Function Pointers,Data Oriented Design,因此,有一条规则试图将if语句从高重复循环中拉出: for( int i = 0 ; i < 10000 ; i++ ) { if( someModeSettingOn ) doThis( data[i] ) ; else doThat( data[i] ) ; } for(int i=0;i
if
语句从高重复循环中拉出:
for( int i = 0 ; i < 10000 ; i++ )
{
if( someModeSettingOn ) doThis( data[i] ) ;
else doThat( data[i] ) ;
}
for(int i=0;i<10000;i++)
{
如果(somemodesetingon)执行此操作(数据[i]);
否则(数据[i]);
}
他们说,最好把它拆散,把if声明放在外面:
if( someModeSettingOn )
for( int i = 0 ; i < 10000 ; i++ )
doThis( data[i] ) ;
else
for( int i = 0 ; i < 10000 ; i++ )
doThat( data[i] ) ;
if(somemodesetingon)
对于(int i=0;i<10000;i++)
doThis(数据[i]);
其他的
对于(int i=0;i<10000;i++)
doThat(数据[i]);
(如果你说“哦!不要自己优化它!编译器会做的!”)请确定优化器可能会为你做这件事。但是在(我不同意他的所有观点,例如他对虚拟函数的态度)中,Mike Acton说:“为什么让编译器猜测你知道的东西呢?对我来说,这些粘滞的东西最有意思
那么为什么不使用函数指针呢
FunctionPointer *fp ;
if( someModeSettingOn ) fp = func1 ;
else fp = func2 ;
for( int i = 0 ; i < 10000 ; i++ )
{
fp( data[i] ) ;
}
FunctionPointer*fp;
如果(somemodesetingon)fp=func1;
else fp=func2;
对于(int i=0;i<10000;i++)
{
fp(数据[i]);
}
函数指针是否存在某种隐藏的开销?它是否与调用直接函数一样有效?在本例中,无法确定哪种情况更快。您需要在目标平台/编译器上分析此代码以估计它 一般来说,在99%的情况下,这样的代码不需要优化。这是一个邪恶的过早优化的例子。
编写人类可读的代码,并仅在分析后需要时对其进行优化。不确定它是否符合“隐藏”条件,但使用函数指针当然需要一个更高级别的间接寻址
编译器必须生成代码来取消对指针的引用,然后跳转到结果地址,而不是直接跳转到常量地址的代码,用于正常的函数调用。不要猜测,测量 但是,如果我一定要猜测的话,我会说第三个变量(函数指针)将比第二个变量(
if
outer-loops)慢,我怀疑这可能会更好地利用CPU的分支预测
第一个变量可能与第二个变量等效,也可能不等效,这取决于编译器的智能程度,正如您已经指出的。您有三种情况:
如果在循环内,函数指针在循环内,如果在循环外
在这三种方法中,没有编译器优化的情况下,第三种方法将是最好的。第一种方法在您想要运行的代码上执行条件引用,第二种方法在代码上执行指针反引用,而第三种方法只运行您想要运行的代码
如果你想自己优化,不要做函数指针版本!如果你不信任编译器进行优化,那么额外的间接操作最终可能会花费你的成本,而且在将来更容易意外中断(在我看来)
为什么要让编译器猜你知道的东西
因为您可能会为将来的维护人员复杂化代码,而不给代码的用户提供任何实质性的好处。这种变化强烈地存在过早的优化,只有在分析之后,我才会考虑除明显的(<代码>如果< /COD>内部循环)之外的任何其他事项。
如果分析表明这是一个问题,那么作为猜测,我相信将if
从循环中拉出会比函数指针更快,因为指针可能会添加编译器无法优化的间接级别。它还将降低编译器内联任何调用的可能性
不过,我也会考虑使用一个抽象接口来代替<代码>如果在循环中。那么每个数据对象已经知道要自动做什么。
你必须测量哪个更快——但是我非常怀疑函数指针的答案会更快。rn处理器具有深度多管道。而函数指针可能会使编译器被迫执行实际的函数调用、推送寄存器等 “为什么要让编译器猜你知道的东西?”您和编译器在编译时都知道一些事情,但处理器在运行时知道更多的事情,比如内部循环中是否有空管道。进行此类优化的日子已经不在嵌入式系统和图形着色器的范围内了。我打赌第二个版本将是