我可以控制 g++ 中的寄存器分配吗?

发布于 2024-07-13 01:56:08 字数 125 浏览 4 评论 0原文

我有高度优化的 C++ 代码,即使在远离热点的地方进行很小的更改,性能也会下降 20%。 经过更深入的调查后发现,热点地区使用的寄存器(可能)略有不同。 我可以使用always_inline属性控制内联,但是我可以控制寄存器分配吗?

I have highly optimized piece of C++ and making even small changes in places far from hot spots can hit performance as much as 20%. After deeper investigation it turned out to be (probably) slightly different registers used in hot spots.
I can control inlineing with always_inline attribute, but can I control register allocation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

何以心动 2024-07-20 01:56:09

如果你真的想搞乱寄存器分配,那么你可以强制 GCC 在某些寄存器中分配局部和全局变量。

您可以使用如下所示的特殊变量声明来执行此操作:

 register int test_integer asm ("EBX");

也适用于其他体系结构,只需将 EBX 替换为目标特定寄存器名称即可。

有关这方面的更多信息,我建议您查看 gcc 文档:

http://gcc.gnu.org/onlinedocs/gcc-4.3.3/gcc/Local-Reg-Vars.html

但是,我的建议是不要弄乱寄存器分配,除非您有非常充分的理由。 如果您自己分配一些寄存器,则分配器可以使用的寄存器较少,并且您最终可能会得到比开始时使用的代码更糟糕的代码。

如果您的函数对性能至关重要,以至于编译之间的性能差异为 20%,那么在内联汇编器中编写该函数可能是个好主意。


编辑:正如斯特拉格指出的那样,编译器不会被迫使用变量的寄存器。 仅当使用变量时才强制使用寄存器。 例如,如果变量无法通过优化传递,则不会使用它。 该寄存器也可用于其他变量。

If you really want to mess with the register alloation then you can force GCC to allocate local and global variables in certain registers.

You do this with a special variable declaration like this:

 register int test_integer asm ("EBX");

Works for other architectures as well, just replace EBX with a target specific register name.

For more info on this I suggest you take a look at the gcc documentation:

http://gcc.gnu.org/onlinedocs/gcc-4.3.3/gcc/Local-Reg-Vars.html

My suggestion however is not to mess with the register allocation unless you have very good reasons for it. If you allocate some registers yourself the allocator has less registers to work with and you may end up with a code that is worse than the code you started with.

If your function is that performance critical that you get 20% performance differences between compiles it may be a good idea to write that thing in inline-assembler.


EDIT: As strager pointed out the compiler is not forced to use the register for the variable. It's only forced to use the register if the variable is used at all. E.g. if the variable it does not survive an optimization pass it won't be used. Also the register can be used for other variables as well.

勿忘心安 2024-07-20 01:56:09

一般来说,所有现代编译器都会忽略寄存器关键字。 唯一的例外是,如果您尝试获取用 register 关键字标记的变量的地址,则(相对)最近添加了一个错误。

我也经历过这种痛苦,最终发现解决这个问题的唯一真正方法是查看输出程序集,尝试确定是什么导致 gcc 陷入困境。 您还可以执行其他操作,但这具体取决于您的代码想要执行的操作。 我正在处理一个非常非常大的函数,其中包含大量计算的 goto 混乱,其中微小的(看似无害的)更改可能会导致灾难性的性能损失。 如果您正在做类似的事情,您可以采取一些措施来尝试缓解问题,但细节有些棘手,所以我将放弃在这里讨论它们,除非它确实相关。

In general the register keyword is simply ignored by all modern compilers. The only exception is the (relatively) recent addition of an error if you attempt to take the address of a variable you've marked with the register keyword.

I've experienced this sort of pain as well, and eventually found the only real way around it was to look at output assembly to try and determine what is causing gcc to go off the deepend. There are other things you can do but it depends on exactly what your code is trying to do. I was working in a very very large function with a large amount of computed goto mayhem in which minor (seemingly innocuous) changes could cause catastrophic performance hits. If you're doing similar there are a few things you can do to try and mitigate the problem, but the details are somewhat icky so i'll forgo discussing them here unless it's actually relevant.

心作怪 2024-07-20 01:56:09

这取决于您使用的处理器。 或者我应该说,是的,您可以使用 register 关键字,但是除非您使用没有管道和单核的简单处理器,否则这是不受欢迎的。 如今,GCC 可以比寄存器分配做得更好。 相信它。

It depends on the processor you are using. Or should I say, yes you can with the register keyword, but this is frowned upon unless you are using a simple processor with no pipe-lining and a single core. These days GCC can do a way better job than you can with register allocation. Trust it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文