gpt4 book ai didi

assembly - mov r64,m64是一个周期还是两个周期的延迟?

转载 作者:行者123 更新时间:2023-12-02 21:38:40 25 4
gpt4 key购买 nike

我在IvyBridge上,我编写了以下简单程序来测量mov的延迟:

section .bss
align 64
buf: resb 64

section .text
global _start
_start:
mov rcx, 1000000000
xor rax, rax
loop:
mov rax, [buf+rax]

dec rcx,
jne loop

xor rdi, rdi
mov rax, 60
syscall


perf显示结果:

 5,181,691,439      cycles


因此,每个迭代都有5个周期的延迟。我从多个在线资源中搜索,L1缓存的延迟为4。因此, mov本身的延迟应为1。

但是,Agner指令表显示 mov r64, m64对于IveBridge具有2个周期的延迟。我不知道其他地方可以找到此延迟。

在上述测量程序中我会出错吗?为什么此程序显示 mov延迟是1而不是2?

(通过使用L2缓存,我得到了相同的结果:如果 buf+rax是L1缺少L2命中,类似的测量结果显示 mov rax, [buf+rax]具有12个周期的延迟。IvyBridge具有11个周期的L2缓存延迟,因此 mov延迟仍然是1个周期)

最佳答案

因此mov本身的延迟应为1。


不,mov是负载。数据也不必经过ALU mov操作。



Agner Fog的指令表不包含负载使用延迟(就像您要测量的那样)。它们在他的microarch PDF中的“缓存和内存访问”部分中的表中,用于每个uarch。例如SnB / IvB(第9.13节)具有“第1级数据”行,其中“ 32kB,8路,64B线大小,每核延迟4”。

此4周期延迟是指一系列相关指令(如mov rax, [rax])的负载使用延迟。您正在测量5个周期,因为您使用的是[reg + 0..2047]以外的寻址模式。对于小位移,加载单元推测直接将基址寄存器用作TLB查找的输入将产生与使用加法器结果相同的结果。 Is there a penalty when base+offset is in a different page than the base?。因此,您的寻址模式[disp32 + rax]使用正常路径,在加载端口中开始TLB查找之前,再等待一个周期以求加法器结果。



对于不同域之间的大多数操作(例如整数寄存器和XMM寄存器),您只能真正测量像movd xmm0,eax / mov eax, xmm0这样的往返行程,很难将其分开并弄清楚每条指令的等待时间是多少分开1。

对于负载,您可以链接到另一个负载以测量缓存负载使用的延迟,而不是存储/重新加载链。

Agner出于某种原因决定只考虑表的存储转发延迟,并对如何在存储和重载之间分配存储转发延迟做出完全任意的选择。


(摘自他的说明表电子表格的“术语定义”表,位于“简介”后的左侧)

无法测量存储器读取或写入的延迟
软件方法指导。只能测量
存储器写入的总延迟,然后是从存储器读取的总延迟
相同的地址。这里测量的实际上不是缓存访问
时间,因为在大多数情况下,微处理器足够智能
直接从写入单元到读取单元的“存储转发”
而不是等待数据进入缓存并再次返回。
该商店转发过程的等待时间可以任意划分
表中的写入延迟和读取延迟。但实际上,
对性能优化有意义的唯一值是总和
写入时间和读取时间。


这显然是不正确的:L1d负载使用等待时间是通过间接级别进行指针追逐的事情。您可能会说它只是可变的,因为某些负载可能会丢失高速缓存,但是如果您要选择要放入表中的内容,则最好选择L1d负载使用延迟。然后计算存储延迟数,使存储+加载延迟=像现在这样转发存储延迟。然后,英特尔Atom的存储等待时间= -2,因为它具有3c L1d load-use latency,但根据Agner的一般指南,存储转发为1c。

例如,这对于加载到XMM或YMM寄存器中不太容易,但是一旦计算出movq rax, xmm0的延迟,仍然可以实现。 x87寄存器更难,因为无法通过ALU将数据从st0直接获取到eax / rax中,而不是存储/重新加载。但是,也许您可​​以使用FP比较来做一些事情,例如fucomi,它直接设置整数FLAGS(在具有它的CPU:P6和更高版本上)。

尽管如此,至少整数加载延迟反映指针追赶延迟要好得多。 IDK(如果有人愿意为他更新Agner的表,或者他愿意接受这样的更新)。不过,对于大多数架构,都需要进行全新的测试,以确保您对不同的寄存器集具有正确的负载使用延迟。



脚注1:例如,http://instlatx64.atw.hu不会尝试,仅在延迟列中说“ diff.reg.set”,而有用数据仅在吞吐量列中。但是他们有MOVD r64, xmm+MOVD xmm, r64往返线路,在IvB上总共in this case 2个周期,因此我们可以确信它们单向仅1c。一种方法不是零。 :P

但是对于装入整数寄存器的寄存器,它们确实显示了IvB对MOV r32, [m32]的4周期装入使用延迟,因为显然它们是在[reg + 0..2047]寻址模式下进行测试的。



缓存延迟信息的其他来源:

https://www.7-cpu.com/提供了许多其他架构的详细信息,甚至包括ARM,MIPS,PowerPC和IA-64之类的非x86架构。

这些页面还有其他详细信息,例如缓存和TLB大小,TLB时序,分支未命中实验结果以及内存带宽。缓存延迟详细信息如下所示:


from their Skylake page


L1数据缓存延迟= 4个周期,用于通过指针进行简单访问
L1数据高速缓存延迟= 5个周期,用于使用复杂地址计算(size_t n, *p; n = p[n])进行访问。
L2缓存延迟= 12个周期
L3缓存延迟= 42个周期(核心0)(i7-6700 Skylake 4.0 GHz)
L3缓存延迟= 38个周期(i7-7700K 4 GHz,Kaby Lake)
RAM延迟= 42个周期+ 51 ns(i7-6700 Skylake)

关于assembly - mov r64,m64是一个周期还是两个周期的延迟?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54072810/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com