Performance 功能对齐在现代处理器上究竟有多重要?
当我在amd64或x86系统上使用最新的编译器编译C代码时,函数将以16字节的倍数对齐。这种对齐在现代处理器上有多重要?调用未对齐的函数是否会带来巨大的性能损失 基准 我运行了以下微基准(Performance 功能对齐在现代处理器上究竟有多重要?,performance,assembly,alignment,x86-64,Performance,Assembly,Alignment,X86 64,当我在amd64或x86系统上使用最新的编译器编译C代码时,函数将以16字节的倍数对齐。这种对齐在现代处理器上有多重要?调用未对齐的函数是否会带来巨大的性能损失 基准 我运行了以下微基准(call.S): 在根据/proc/cpuinfo将自身标识为Intel(R)Core(TM)i7-2760QM CPU@2.40GHz的CPU上。偏移量对我没有影响,基准测试持续运行了1.9秒 另一方面,在另一个CPU自称为Intel(R)Core(TM)i7 CPU L640@2.13GHz的系统上,基准测
call.S
):
在根据/proc/cpuinfo
将自身标识为Intel(R)Core(TM)i7-2760QM CPU@2.40GHz的CPU上。偏移量对我没有影响,基准测试持续运行了1.9秒
另一方面,在另一个CPU自称为Intel(R)Core(TM)i7 CPU L640@2.13GHz的系统上,基准测试需要6.3秒,除非偏移量为14或15,其中代码需要7.2秒。我认为这是因为函数开始跨越多个缓存线;DR:缓存对齐很重要。您不需要无法执行的字节
至少,您希望避免在执行第一个指令之前获取指令。由于这是一个微基准测试,您很可能看不到任何差异,但是想象一下在一个完整的程序中,如果由于第一个字节没有与缓存线对齐而在一组函数上有额外的缓存未命中,那么您最终必须为函数的最后N个字节获取一个新的缓存线(其中N请定义未对齐的x86指令/地址?x86是可变长度指令,因此您几乎总是未对齐。整个体系结构基于处理未对齐的指令,大多数分支目标是unaligned@dwelch:gcc对齐函数的入口点(即其第一条指令)16个字节的倍数。@ GJ。考虑它完成了。它是一个预取优化,不仅仅是函数,而且是分支目标。没有什么可以用一个简单的循环来测试。@汉斯巴顿可能。我不知道如何为这样的事情做基准。英特尔在2020年5月删除了所有分支目标16的建议;没有UP缓存的CPU。e现在基本上是不相关的,在函数内部以32对齐是不值得的;对于函数,以16对齐通常仍然是由编译器完成的,并且对我来说似乎是合理的。另请参见其他相关Q&A,如
// benchmarking performance penalty of function alignment.
#include <sys/syscall.h>
#ifndef SKIP
# error "SKIP undefined"
#endif
#define COUNT 1073741824
.globl _start
.type _start,@function
_start: mov $COUNT,%rcx
0: call test
dec %rcx
jnz 0b
mov $SYS_exit,%rax
xor %edi,%edi
syscall
.size _start,.-_start
.align 16
.space SKIP
test: nop
rep
ret
.size test,.-test
#!/bin/sh
for i in `seq 0 15` ; do
echo SKIP=$i
cc -c -DSKIP=$i call.S
ld -o call call.o
time -p ./call
done