每条CPU指令消耗许多字节。大小越小,CPU缓存中可以保存的指令越多。
编写允许您减少CPU指令大小的C ++代码时有哪些可用的技术?
一个例子可能是减少FAR跳转的次数(字面意思是跳转到更大地址的代码)。由于偏移量较小,因此使用的类型较小,整体指令较小。
我认为GCC的__builtin_expect可以通过将不太可能的指令放得更远来减少跳转指令的大小。
我认为我已经看到使用int32_t而不是int16_t更好,因为它是本机CPU整数大小,因此CPU指令更有效。
或者只能在编写汇编时才能完成?
答案 0 :(得分:2)
现在我们都在讨论微观/宏观优化问题,让我们尝试帮助解决实际问题。
我没有完整,明确的答案,但您可以启动here。 GCC有一些宏钩子用于描述目标硬件的性能特征。理论上你可以设置一些关键的宏来帮助gcc青睐"更小的"优化时的说明。
根据来自this question及其one reply的非常有限的信息,您可以从TARGET_RTX_COSTS费用挂钩获得一些收益。我还没有做足够的后续研究来验证这一点。
我猜想像这样挂钩编译器会比任何特定的C ++习惯用法更有用。
如果您管理任何性能提升,请告诉我们。我很好奇。
答案 1 :(得分:1)
如果处理器有各种长度(多字节)指令,那么您可以做的最好的事情是编写代码以帮助编译器使用较小的指令大小。
调试优化代码比调试未优化的代码更困难。调试器使用的符号与源代码更好地对齐。在优化期间,编译器可以消除代码,这会使代码与源列表不同步。
并非所有处理器都有可变长度指令。熟悉处理器指令集。找出哪些指令很小(一个字节)与多字节。
编写代码以使用小型装配说明 帮助编译器并编写代码以利用小长度指令。
打印汇编语言代码以验证编译器是否使用小指令。
如有必要,请更改代码以帮助编译器。
无法保证编译器会使用小指令。根据优化设置,编译器会发出它认为具有最佳性能的指令。
生成汇编语言源代码后,您现在可以更好地用汇编语言版本替换高级语言。您可以自由使用小指令。
在所有情况下,较小的指令可能不是最佳解决方案。例如,英特尔处理器具有块指令(对数据块执行操作)。这些块指令的性能优于小指令的循环。但是,块指令比较小的指令占用更多的字节。
处理器将根据指令将所需的字节数提取到其指令高速缓存中。如果您可以编写适合缓存的循环或代码,那么指令大小就不那么重要了。
此外,许多处理器将使用大指令与其他处理器通信,例如浮点处理器。减少程序中的浮点数学可能会降低这些指令的质量。
通常,分支会降低处理速度。分支是将执行更改为新位置,例如循环和函数调用。处理器喜欢数据指令,因为它们不必重新加载指令管道。增加数据指令的数量和减少分支的数量将提高性能,通常不考虑指令大小。