问题描述
我正在对JIT编译器进行编程,但我惊讶地发现,在Win64调用约定中,许多x86-64寄存器都是非易失性的(被调用者保留)。在我看来,非易失性寄存器在使用这些寄存器的所有功能中仅能完成更多工作。在数值计算的情况下尤其如此,在这种情况下,您希望在叶函数中使用许多寄存器,例如某种高度优化的矩阵乘法。但是,例如,在16个SSE寄存器中只有6个是易失的,因此,如果您需要使用更多的寄存器,则会有很多工作要做。
I'm programming a JIT compiler and I've been surprised to discover that so many of the x86-64 registers are nonvolatile (callee-preserved) in the Win64 calling convention. It seems to me that nonvolatile registers just amount to more work in all functions that could use these registers. This seems especially true in the case of numeric computations where you'd want to use many registers in a leaf function, say some kind of highly optimized matrix multiplication. However, only 6 of the 16 SSE registers are volatile, for example, so you'd have a lot of spilling to do if you need to use more than that.
是的,我不明白。在这里要权衡什么?
So yeah, I don't get it. What's the tradeoff here?
推荐答案
如果寄存器是调用者保存的,那么调用者总是在函数调用周围保存或重新加载这些寄存器。但是,如果寄存器是被调用者保存的,那么被调用者只需保存其使用的寄存器,并且仅在知道将要使用它们时才保存(即,在提早退出的情况下可能根本不保存)。 this 约定的缺点是被调用者不了解调用者,因此它可能会保存已死的寄存器,但我想这是一个较小的问题。
If registers are caller-saves, then the caller always has to save or reload those registers around a function call. But if registers are callee-saves, then the callee only has to save the registers that it uses, and only when it knows they're going to be used (i.e. maybe not at all in an early-exit scenario). The disadvantage of this convention is that the callee doesn't have knowledge of the caller, so it might be saving registers that are dead anyway, but I guess that's seen as a smaller concern.
这篇关于在调用约定中具有非易失性寄存器的优点是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!