从 Haswell 开始,英特尔 CPU 微架构在端口 7 上有一个专用的存储地址单元,它可以处理某些存储操作的地址生成 uop(另一个 uop,存储数据总是转到端口 4(。
最初人们认为这可以处理任何类型的地址,但事实似乎并非如此。此端口可以处理哪些类型的地址?
这个答案适用于Haswell和Skylake(/Kaby Lake/Coffee Lake(。 未来的ISA(Cannon Lake/Ice Lake(必须在可用时进行检查。 端口 7 AGU 是哈斯韦尔的新端口。
对于完全可以使用端口 7 的指令(例如不vextracti128
(,任何非索引寻址模式都可以使用端口 7。
这包括 RIP 相对和 64 位绝对(mov [qword abs buf], eax
,即使在加载超过 2^32 的 PIE 可执行文件中,所以地址真的不适合 32 位(,以及正常的[reg + disp0/8/32]
或绝对[disp32]
。
索引寄存器始终阻止使用 port7,例如[rdi + rax]
,或[disp32 + rax*2]
。 即使[NOSPLIT disp32 + rax*1]
也不能使用端口 7(因此 HSW/SKL 不会在内部将 scale=1 且没有基本寄存器的索引转换为 base+disp32 寻址模式。
我在Skylake i7-6700k上用ocperf.py stat -etask-clock,context-switches,cpu-migrations,page-faults,cycles,instructions,uops_dispatched_port.port_2,uops_dispatched_port.port_3,uops_dispatched_port.port_7 ./testloop
测试了自己。
[+0, +2047]
排量范围对商店没有什么不同:mov [rsi - 4000], rax
可以使用端口 7。
具有小正位移的非索引负载的延迟降低了 1c。 英特尔的优化手册中没有提到商店的特殊情况。 Skylake的可变延迟存储转发(当负载尝试在存储后立即执行时延迟更差(使得很难构建包含存储延迟的微基准测试,但不受存储地址uops与负载竞争更少端口的影响。 我还没有想出一个微基准测试,通过存储地址uop而不是通过存储数据uop来循环携带依赖链。 大概这是可能的,但可能需要一个数组而不是单个位置。
某些指令根本无法使用 port7:
vextracti128 [rdi], ymm0, 0
包括存储地址 UOP(当然(,但它只能在端口 2 或端口 3 上运行。
不过,Agner Fog的指令表至少有一个错误:他pextrb/w/d/q
列出只在p23上运行存储地址uop,但实际上它可以在HSW/SKL上使用p237中的任何一个。
我没有对此进行详尽的测试,但是我发现HSW和 SKL 之间的一个区别是 1VCVTPS2PH [mem], xmm/ymm, imm8
. (指令更改为使用更少的 ALU uops,因此这并不表示 HSW 和 SKL 之间的 p7 发生变化(。
-
在哈斯韦尔:
VCVTPS2PH
是4 uops(融合和未融合域(:p1 p4 p5 p23(Agner Fog是对的(。 -
在天湖上:
VCVTPS2PH xmm
是 2 个熔断器/3 个未熔断的 uops:p01 p4 p237 -
在天湖上:
VCVTPS2PH ymm
是 3 个熔断器/3 个未熔断器:p01 p4 p237(Agner Fog 将
VCVTPS2PH v
列为 3F/3U(两个矢量宽度一个条目(,缺少与 xmm 版本的微融合,并错误地将端口细分列为 p01 p4 p23(。
一般来说,请注意 Agner 最近的更新似乎有点草率,例如复制/粘贴或拼写错误(例如,Ryzenvbroadcastf128 y,m128
吞吐量为 5 而不是 0.5(。
1:HSW测试是在一台不再可用的旧笔记本电脑上进行的(我使用它的RAM升级了另一台仍然经常使用的机器(。 我没有布罗德韦尔可以测试。 这个答案中的所有内容在Skylake上都是绝对正确的:我刚才仔细检查了一下。 不久前我在Haswell上测试了其中的一些,并且仍然保留了我的笔记。