c++ - 在调用者方法中衰减多个函数

标签 c++ performance templates

这个问题主要与我遇到的大型代码维护和可重用性问题有关。我有几个类有这样的方法:

void MyClassX::Draw(){

   ///Some large chunk of code#1 here


   ///Another large chunk of code#2 goes here


   ///Another large chunk of code#3 goes here

}


void MyClassY::Draw(){

   ///Some large chunk of code#1 here


   ///Another large chunk of code#2 goes here

}

该方法的变体之间的区别在于,其中一些代码块在不同的类中是可选的。 现在,这可能听起来很愚蠢,但因为该方法会执行一些性能关键的实时处理(3D 渲染)。我不会对这些代码块使用函数,也不想用这些函数来包装它们,因为我试图减少一般函数调用的数量。我想要的是在某个 block 中定义这些函数(例如使用 #define),然后在 void Draw() 内的适当位置声明这些函数而不是整个代码块。我不想使用预处理器,因为很难编辑这样的代码(没有适当的错误提示或调试)。我认为的另一个选择是内联函数。但因为编译器不保证内联,我不确定这种方式是否有效。还有其他技巧吗?也许通过 C++ 模板的使用?我可以强制某些函数体在调用者方法内衰减吗?

附注出于性能考虑,我也不对这些类使用继承,因为它基本上也可以通过将所有这些 block 定义为基类中的函数来解决该问题。同样在 void Draw() 内部,我尝试将条件分支减少到最低限度。

最佳答案

有一些方法可以在某些编译器上强制内联函数,例如 __forceinline在 MSVC 或 __attribute__((always_inline))关于海湾合作委员会。它是特定于编译器的,但您可以通过一些注意事项来保证它。在那里,我建议检查您的编译器文档,并习惯于在广泛的层面上分析反汇编(例如,足以识别函数调用,这相当容易,因为您可以使用调试器跟踪它并注意到它何时分支)。

也就是说,我真的认为你可能看错了。我可能是错的,也许你有我以前没有遇到过的非常特殊的需求,但我处于一个性能关键的领域,除了正确性之外,效率通常与产品的感知质量成正比(我' m 也是 3D 格式,包括路径追踪)。

我习惯于使用分析器进行工作,并且我学会了对优化器持保留态度。有些事情优化器和标准库做得不太好,而我习惯于做一些事情,比如滚动我自己的内存分配器并获得相当大的 yield 。

但在我的无数次分析 session 中,我从未遇到过编译器在函数调用开销方面表现不佳的情况。我见过优化器出现问题,并且在指令选择或寄存器分配方面做得很差,其中以某种实际上无济于事的方式重写代码,却有助于发出更有效的汇编。这包括将一些大块代码转换为更多函数,您认为这不会提高性能,但可以帮助编译器完成这两个领域(寄存器分配和指令选择)。

我在优化中发现的更有用的事情之一是优化器可能很棒,但它们不了解在运行时将收到什么样的用户输入。这是常见案例执行的一个关键方面,只有了解产品设计的人才能预见到。所以我发现的一件事是,将代码的罕见情况分支放入单独的、未内联的函数中,这样逻辑就不会全部内联在一个巨大的 blob 中,实际上在某种程度上有所帮助(没有调查所有这些的反汇编)情况下,只是注意到有时的改进)。我认为这只是帮助编译器不要将所有代码视为一种平坦的竞争环境,帮助它更有选择性地/局部地进行优化,因为例如只有这么多寄存器,并将所有内容都放在一个巨大的寄存器中函数可能会让优化器混淆哪部分需要更多关注。

也就是说,我发现在分析和优化期间使用更集中的代码通常很有帮助。这并不是因为在大型函数中使用更集中的代码实际上可以加快速度,而是因为当您试图提高微观层面的效率时,使用结构化程度较低的代码会更容易。在对事物进行微调之后强加更多的结构比在进行详尽的分析 session 之前试图解开它更容易,因此有时以这种方式编写代码并为了大的牺牲一些整洁性和结构会很有帮助。代码块。但这样做的好处还在于,在分析此类代码并事后获得效率知识以帮助组织代码后,可以轻松更改此类代码;我从未见过这样的代码实际上能让事情变得更快。

所以我真的认为你最好不要过多关注内联,而将其更多地留给优化器。即使在最小的微观效率水平上,通常也有更好的事情需要优化,可以获得更明显的 yield 。

关于c++ - 在调用者方法中衰减多个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30376653/

相关文章:

c++ - 改变成员 vector 的类型

c++ - 如何按修改日期列出目录中的文件?

python - 有什么办法可以加快 Pandas 比较的速度吗?

c++ - Visual Studio 在引用堆栈变量时不使用 EBP

Python-在数组中创建唯一值的掩码

excel - 将多个值插入多个不同的单元格

c# - 使用语句实现与 C# 等效的 C++

c++ - 如何解决 - 错误 : there are no arguments to 'exit' that depend on a template parameter

c++ - C++ 中的 BloomFilter 使用 MurmurHash3 哈希函数

c++ - 制作图书馆时是否应避免使用宏