为何x86-64 Linux ABI用寄存器传递小于16字节的结构体而非8字节?
x86-64 ABI为啥要等结构体超16字节才用内存传递?
核心逻辑:寄存器利用率比单一字长分界更重要
x86-64的通用寄存器都是8字节,但ABI允许用两个连续寄存器传递总大小≤16字节的结构体——这不是死板卡8字节的线,而是为了最大化寄存器的使用效率。
- 比如两个
long组成的16字节结构体,直接塞进rdi和rsi寄存器传递,被调用者能直接从寄存器拿数据,根本不需要碰内存。要是改成传指针,被调用者还得多一次从内存加载的操作,反而更慢。 - 要是把分界设成8字节,那所有超过8字节的结构体都得走指针传递,等于白白浪费了另一个寄存器的空间,平白增加内存访问开销,完全没必要。
16字节是寄存器传递的合理边界
x86-64调用约定里,前几个寄存器(rdi、rsi、rdx这些)是固定用来传参数的。结构体传递时,ABI允许把它拆成多个寄存器传,但最多用两个寄存器(16字节)——这是在寄存器资源和传递效率之间的折中:
如果结构体超过16字节,继续用寄存器传递就得占用更多寄存器,而寄存器是有限的,占多了会导致其他参数、局部变量不得不溢出到内存,反而拖慢整体性能。这时候改用内存传递(调用者在栈上开空间放结构体,传地址给被调用者),反而能平衡开销。
实际代码生成的差异
拿16字节和24字节的结构体对比:
- 16字节结构体:调用者直接把两个成员分别放进
rdi和rsi,被调用者直接读寄存器,无额外内存操作。 - 24字节结构体:调用者先在栈上分配空间存结构体,把数据写进去,再把栈地址传给被调用者,后者得从栈里读数据,多了一次内存读写。
说白了就是:16字节以内用寄存器传,比传指针再读内存更快;超过16字节后,寄存器不够用,内存传递反而更划算。
内容的提问来源于stack exchange,提问作者Joseph Garvin
相关产品推荐
相关产品推荐

