【问题标题】:Global variable in a register寄存器中的全局变量
【发布时间】:2018-04-12 11:55:29
【问题描述】:

这是否可以告诉编译器将某个全局变量放入寄存器中?因此有效地阻止了该寄存器在其他任何地方的使用。我知道这可能很困难,因为即使是对malloc() 的简单调用也需要暂时溢出。

我正在考虑它,因为我正在寻找一种方法来有效地为某种 VM 实现辅助堆栈,自然将辅助堆栈指针存储在另一个寄存器中会很棒。

【问题讨论】:

  • 它可能取决于编译器,但我认为在 gcc 中类似 register int *foo asm ("r12"); 的全局范围内的东西会起作用。见6.44.5.1 Defining Global Register Variables
  • @FlávioToribio:你可以做到这一点,但这当然需要所有模块都必须正确编译。包括标准库。或者 ABI 必须保证寄存器不会被函数破坏。这通常只对非常特殊的软件有意义,例如操作系统内核或裸机嵌入式。对于“正常”的应用程序代码,甚至考虑它都是不合理的。
  • 更重要的是,这似乎是一个 XY 问题。
  • @EOF:我认为根本不存在 Y 问题。这只是一些不成熟(而且很可能有害)的优化方法。
  • @Someprogrammerdude:我不认为 Flavio 表示 register 关键字,而是带有 gcc 扩展的整个构造。这实际上分配了 rewgister fort 变量。当然,如果其他代码不知道这个保留,你就有麻烦了。

标签: c optimization cpu-registers


【解决方案1】:

理论上,这是可能的:您可以获取调用约定需要在函数调用之间保留的任何寄存器,并将其用于您的全局变量。

但是,这样做存在一些问题:

  • 效果是,您的函数将少一个可用的局部变量寄存器。这意味着平均有更多的内存访问。

  • 库函数将保留寄存器值,它们会将其保存在堆栈中,就像任何其他非 clobber 寄存器一样,随意使用它,并在返回之前恢复它。

  • 因此,不可能将回调指针传递给库函数,并从回调中访问全局寄存器。 (但这可能不是你的问题。)

  • 如果您将 VM 堆栈实现为全局变量,那么您一开始就做错了事。堆栈本质上应该是线程本地的,它没有全局业务。

正确地做事,将堆栈指针保留为 VM 模拟器中的局部变量可能会为您提供可以获得的最佳性能。

【讨论】:

    【解决方案2】:

    这是否可以告诉编译器将某个全局变量放入寄存器中?

    不是真的。有register 存储类,但这仅意味着变量应该“尽可能快”。这个关键字现在大多已经过时了,它是从编译器垃圾的时代开始的。

    因此有效地阻止此寄存器在其他任何地方使用

    无法选择特定的寄存器。为此,您必须使用内联汇编程序。

    我正在考虑它,因为我正在寻找一种方法来有效地为某种 VM 实现辅助堆栈,自然将辅助堆栈指针存储在另一个寄存器中会很棒。

    听起来您需要整体编写汇编程序。甚至不可能从 C 中设置堆栈指针。或者,如果“堆栈”不是指程序内存,而是某种数据类型,那么首先不要摆弄过早的优化。

    【讨论】:

      猜你喜欢
      • 2015-02-06
      • 2020-02-07
      • 2015-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-15
      • 2010-11-18
      • 1970-01-01
      相关资源
      最近更新 更多