迭代而不会产生IF语句的成本

Sam*_*rsa 5 c++

我的问题是基于好奇心,而不是是否有另一种方法来解决问题.这是一个奇怪/有趣的问题,所以请以开放的心态阅读.

让我们假设每个帧都有一个游戏循环.游戏循环依次通过无数的if语句调用几个函数.例如,如果用户将GUI设置为false,则不刷新GUI,否则调用RefreshGui().if循环中还有许多其他语句,如果它们是真的,它们会调用它们各自的函数.if/if-else.../else在最坏的情况下,有些是更昂贵的.如果if语句为真,即使被调用的函数也有逻辑.如果用户想要在所有对象上调用raypicking FunctionA(),如果用户想要对灯光进行raypick,请调用FunctionB(),...,否则调用所有函数.希望你明白了.

我的观点是,这是多余的if语句.所以我决定使用函数指针.现在我的假设是函数指针总是比if语句更快.它是if/else的替代品.因此,如果用户想要在两种不同的相机模式之间切换,则他/她按下C键以在它们之间切换.键盘的回调函数将函数指针更改为正确的UpdateCamera函数(在这种情况下,函数指针可以指向UpdateCameraFps()或者UpdateCameraArcBall())...你得到它的要点.

现在问题本身.如果我有几个具有相同签名的更新函数(假设为void (*Update)(float time)),那么函数指针可能指向其中任何一个.然后,我有一个用于存储指针的向量.然后在我的主更新循环中,我浏览向量并调用每个更新函数.我可以删除/添加甚至更改更新的顺序,而无需更改底层代码.在最好的情况下,我可能只调用一个更新函数,或者在最坏的情况下调用所有这些函数,所有这些都具有非常干净的while循环并且没有讨厌的(可能是嵌套的)if语句.我已经实现了这个部分,效果很好.我知道,随着while循环的每次迭代负责迭代向量,我正在检查是否itrBegin == itrEnd.进一步来说while (itrBegin != itrEnd).有没有办法避免调用if语句?我可以使用分支预测对我有利(或者我在不知情的情况下利用它)?

再次,请按原样提出问题,即我不是在寻找一种不同的方法(尽管您非常欢迎提供一种方法).

编辑:一些回复表明这是一个不必要的过早优化,我不应该专注于它,并且if语句的成本与所有单独的更新函数中完成的工作相比是微不足道的.非常的,我完全同意,但这不是问题的关键,如果我没有让问题更清楚,我会道歉.尽管如此,我确实学到了很多新的东西!

Ben*_*igt 6

每一帧都有一个游戏循环

这是描述它的倒退方式.游戏循环在帧期间不运行,帧在游戏循环体中处理.

我的假设是函数指针总是比if语句快

你测试过了吗?它不太可能是真的,特别是如果你经常更改指针(这真的与CPU的分支预测混淆).

我可以使用分支预测对我有利(或者我在不知情的情况下利用它)?

这只是一厢情愿的想法.通过在循环中调用一堆不同的函数进行间接调用,您肯定会对CPU分支预测逻辑起作用.

更具体地说是(itrBegin!= itrEnd).有没有办法避免调用if语句?

在迭代函数链时,为了避免条件,你可以做的一件事是使用链表.然后每个函数都可以无条件地调用下一个函数,只需将终止逻辑安装为链中的最后一个函数(longjmp或其他).或者你可能希望永远不会终止,包括glSwapBuffers(或图形API的等价物)在列表中,只需将其链接回到开头即可.

  • 而不只是分支预测!使用函数指针将阻止编译器内联,这可能会大大减少优化机会 - 函数调用(内联避免)的开销是简单if语句的几倍.如果代码是内联的并且在指令缓存中,它可能比函数指针调用快几百倍! (2认同)

小智 5

首先,分析您的代码。然后优化需要的部分。

“if”语句是您最不关心的问题。通常,通过优化,您将重点关注低效且频繁使用的循环、I/O 操作、API 调用(例如 SQL)、容器/算法。

使用函数指针来尝试优化通常是最糟糕的事情。你会扼杀任何代码可读性的机会,并且对 CPU 和编译器不利。我建议使用多态性或仅使用“if”语句。

  • 多态性只是函数指针之上的附加间接层(可能具有可怕的局部性)。 (3认同)