首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在调用约定中使用非易失性寄存器有什么好处?

在调用约定中使用非易失性寄存器有什么好处?
EN

Stack Overflow用户
提问于 2012-05-01 10:35:20
回答 4查看 1.4K关注 0票数 3

我正在编写一个即时编译器,我惊讶地发现,在Win64调用约定中,如此多的x86-64寄存器是非易失性的(被调用方保留的)。在我看来,在所有可以使用非易失性寄存器的函数中,非易失性寄存器只是意味着更多的工作。这在数值计算的情况下尤其如此,在这种情况下,你想在一个叶函数中使用许多寄存器,比如某种高度优化的矩阵乘法。但是,例如,16个SSE寄存器中只有6个是易失性寄存器,因此如果您需要使用更多寄存器,则需要进行大量溢出操作。

所以,是的,我不明白。这里的权衡是什么?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-05-01 10:46:15

如果寄存器是调用者保存的,那么调用者总是必须在函数调用期间保存或重新加载这些寄存器。但是如果寄存器是被调用保存的,那么被调用方只需保存它所使用的寄存器,并且仅当它知道它们将被使用时(即,在提前退出的场景中可能根本不需要)。这种约定的缺点是被调用者不知道调用者,所以它可能会保存已死的寄存器,但我猜这被视为一个较小的问题。

票数 5
EN

Stack Overflow用户

发布于 2017-11-10 00:30:15

Windows x86-64调用约定只有6个被调用的xmm寄存器,这不是一个很好的设计,您是对的。大多数SIMD (和许多标量FP)循环不包含任何函数调用,因此它们不会从调用保留寄存器中获得任何数据。保存/恢复是纯粹的缺点,因为它比任何调用者使用这种非易失性状态的情况都要少。

在x86-64系统V中,所有的向量寄存器都是被调用的,这可能是另一种方式太远了。在许多情况下,保留一个或两个调用会很好,特别是对于进行一些数学库函数调用的代码。(Use gcc -fno-math-errno to let simple ones inline better;有时他们不这样做的唯一原因是他们需要在NaN上设置errno。)

相关:how the x86-64 SysV calling convention was chosen:查看用于gcc编译SPECint/SPECfp的代码大小和指令计数。

对于整数,每个都有一些的绝对是很好的,而且所有“正常”的调用约定(对于所有架构,不仅仅是x86)实际上都有一个混合。这减少了在调用方和被调用方的总和中完成的溢出/还原的总工作量。

强制调用者溢出/重新加载每个函数调用周围的所有内容对代码大小或性能都不好。在函数开始/结束时保存/恢复一些调用保留的regs,可以让非叶函数在跨call的寄存器中保留一些内容。

考虑一些计算一些事情的代码,然后执行cout << "result: " << a << "foo" << b*c << '\n';,这是对std::ostream operator<<的4个函数调用,它们通常不内联。在非易失性寄存器中保留您刚才计算的cout和本地变量的地址,这意味着您只需要一些廉价的mov reg,reg指令就可以为下一次调用设置参数。(或堆栈参数调用约定中的push )。

但是拥有一些不需要保存就可以使用的被调用的寄存器也是非常重要的。不需要所有体系结构寄存器的函数可以只使用被调用的寄存器作为临时寄存器。这避免了在调用者的依赖链(对于非常小的被调用者)的关键路径中引入溢出/重新加载,以及节省指令。

有时,一个复杂的函数会保存/恢复一些调用保留的寄存器,以获得更多的总寄存器(就像您在使用XMM处理数字时看到的那样)。这通常是值得的;保存/恢复调用者的非易失性寄存器通常比溢出/重新加载您自己的局部变量到堆栈要好,特别是如果您必须在任何循环中这样做的话。

调用重写寄存器的另一个原因是,通常在函数调用后,您的一些值是“死的”:您只需要将它们作为函数的参数。在被调用的寄存器中计算它们意味着你不需要保存/恢复任何东西来释放这些寄存器,而且你的被调用者也可以自由地使用它们。这在调用在寄存器中传递arg的约定时甚至更好:您可以直接在arg传递寄存器中计算输入。(如果您在函数之后也需要它们,则复制它们以调用保留的regs或将它们溢出到堆栈内存中。)

(我喜欢call-saved和call-clobbered这两个术语,而不是caller-saved和callee saved。后一种术语意味着必须有人保存寄存器,而不是让死值消失。易失性/非易失性不坏,但这些术语还具有其他技术含义,如C关键字,或闪存与DRAM的术语。)

票数 1
EN

Stack Overflow用户

发布于 2016-01-16 16:04:46

拥有nonvolatile寄存器的优点是:performance

移动的数据越少,CPU的效率就越高。

volatile寄存器越多,所需的能量就越多。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10392895

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档