例如,x86位操作指令(btr、bts、btc、no lock)应用于内存操作数比其他读-修改-写指令(如add、xor等)在大多数支持它们的处理器上要慢。为什么会这样呢?这些指令看起来很容易实现。这是因为实际加载的地址与内存操作数指定的地址不同,而这混淆了一些跟踪内存访问的前端机制吗?这似乎是合理的,但我不认为它会影响吞吐量(至少不会影响这么多);只有等待时间。
8dtrkrch1#
是因为实际加载的地址与内存操作数指定的地址不同吗是的,很明显,这就是它与记忆-目的地转移的区别。reg-reg版本在Intel上是具有1个周期延迟的1个uop,例如在Intel Haswell和更高版本上运行在执行端口0或6上,与移位相同。(将索引解码为1-hot掩码比一般移位器便宜,但由于存在移位单元,推测Intel只使用这些移位单元。)AMD由于某种原因运行bts reg,reg为2 uops,比简单的移位慢。IDK为什么,也许是关于标志设置的东西。bts mem, imm8也很正常,Intel上有3个前端uop。xor mem, imm8只有2个前端uop,但这是因为它可以微融合加载+xor。not mem有3个前端uop,仅微融合存储地址和存储uop指令。这会混淆跟踪内存访问的前端机制吗不,前端不跟踪内存访问,那是后端。它之所以慢,部分原因是因为它是作为多个微指令实现的;即使你执行一个被不同指令包围的任务也会很痛苦。在IntelHaswell和桤木(可能都在两者之间)上,bts mem, r32需要10个前端微操作,而bts mem, imm8需要3个因为它不能直接使用通常的地址生成硬件,所以它在微码中实现为多个uop,大概类似于从正常寻址模式到临时地址的莱亚,并向其添加(bit_index>>6) * 4,以便通过dword或类似的方式进行索引。哦,它是10个uop的原因可能是它总是希望访问包含该位的 aligned dword,而不仅仅是从X1 M7 N1 X寻址模式中的地址偏移4的倍数,用于类似X1 M8 N1 X的东西。在正常情况下,手动执行此操作效率更高,因为您知道位字符串的开头是对齐的,因此可以shr位索引以获取用于load /bts reg,reg的双字索引(1uop)/ store。这比bts [mem], reg占用更少的uop。注意,bts reg,reg截断/ Package 位索引,所以如果你正确地安排事情,模是免费的。例如埃拉托塞尼的筛子。也可以是 * How can memory destination BTS be significantly slower than load / BTS reg,reg / store? *但是Agner Fog和https://uops.info/都在Haswell /桤木Lake P核上测量了5个周期的吞吐量,大大低于前端瓶颈(或任何每端口后端瓶颈)。
bts reg,reg
bts mem, imm8
xor mem, imm8
not mem
bts mem, r32
(bit_index>>6) * 4
shr
bts [mem], reg
实际的加载和存储微操作应该是正常的,输入来自内部临时寄存器,但就存储缓冲区和加载缓冲区中的地址而言,仍然是正常的加载微操作和存储微操作(英特尔称之为内存顺序缓冲区= MOB)。
我并不认为这是内存依赖预测的特例,因为这是在加载微操作执行时发生的(还有一些存储地址微操作尚未执行,因此一些先前存储的地址仍然未知)。TODO:运行一些实验,看看是否有任何其他指令与bts mem,reg混合在一起会降低它的速度,争夺它瓶颈所在的任何资源。这看起来不像是https://uops.info/方面的基准测试错误(例如,每次使用相同的地址,并停止存储转发延迟)。他们的测试包括一些使用不同偏移量的展开序列。例如,Haswell throughput testing for bts m64, r64每次使用相同的地址测量6.02或6.0周期吞吐量(bts qword ptr [r14], r8),或者当展开像bts [r14],r8的重复序列时每个BTS平均5.0个周期;bts [r14+0x8],r8 ;即使对于覆盖两个相邻高速缓冲存储器线的16个独立指令的序列,其每迭代仍为相同的5个循环。
bts mem,reg
bts m64, r64
bts qword ptr [r14], r8
bts [r14],r8
bts [r14+0x8],r8
1条答案
按热度按时间8dtrkrch1#
是因为实际加载的地址与内存操作数指定的地址不同吗
是的,很明显,这就是它与记忆-目的地转移的区别。
reg-reg版本在Intel上是具有1个周期延迟的1个uop,例如在Intel Haswell和更高版本上运行在执行端口0或6上,与移位相同。(将索引解码为1-hot掩码比一般移位器便宜,但由于存在移位单元,推测Intel只使用这些移位单元。)
AMD由于某种原因运行
bts reg,reg
为2 uops,比简单的移位慢。IDK为什么,也许是关于标志设置的东西。bts mem, imm8
也很正常,Intel上有3个前端uop。xor mem, imm8
只有2个前端uop,但这是因为它可以微融合加载+xor。not mem
有3个前端uop,仅微融合存储地址和存储uop指令。这会混淆跟踪内存访问的前端机制吗
不,前端不跟踪内存访问,那是后端。
它之所以慢,部分原因是因为它是作为多个微指令实现的;即使你执行一个被不同指令包围的任务也会很痛苦。在IntelHaswell和桤木(可能都在两者之间)上,
bts mem, r32
需要10个前端微操作,而bts mem, imm8
需要3个因为它不能直接使用通常的地址生成硬件,所以它在微码中实现为多个uop,大概类似于从正常寻址模式到临时地址的莱亚,并向其添加
(bit_index>>6) * 4
,以便通过dword或类似的方式进行索引。哦,它是10个uop的原因可能是它总是希望访问包含该位的 aligned dword,而不仅仅是从X1 M7 N1 X寻址模式中的地址偏移4的倍数,用于类似X1 M8 N1 X的东西。在正常情况下,手动执行此操作效率更高,因为您知道位字符串的开头是对齐的,因此可以
shr
位索引以获取用于load /bts reg,reg
的双字索引(1uop)/ store。这比bts [mem], reg
占用更少的uop。注意,bts reg,reg
截断/ Package 位索引,所以如果你正确地安排事情,模是免费的。例如埃拉托塞尼的筛子。也可以是 * How can memory destination BTS be significantly slower than load / BTS reg,reg / store? *但是Agner Fog和https://uops.info/都在Haswell /桤木Lake P核上测量了5个周期的吞吐量,大大低于前端瓶颈(或任何每端口后端瓶颈)。
实际的加载和存储微操作应该是正常的,输入来自内部临时寄存器,但就存储缓冲区和加载缓冲区中的地址而言,仍然是正常的加载微操作和存储微操作(英特尔称之为内存顺序缓冲区= MOB)。
我并不认为这是内存依赖预测的特例,因为这是在加载微操作执行时发生的(还有一些存储地址微操作尚未执行,因此一些先前存储的地址仍然未知)。
TODO:运行一些实验,看看是否有任何其他指令与
bts mem,reg
混合在一起会降低它的速度,争夺它瓶颈所在的任何资源。这看起来不像是https://uops.info/方面的基准测试错误(例如,每次使用相同的地址,并停止存储转发延迟)。他们的测试包括一些使用不同偏移量的展开序列。例如,Haswell throughput testing for
bts m64, r64
每次使用相同的地址测量6.02或6.0周期吞吐量(bts qword ptr [r14], r8
),或者当展开像bts [r14],r8
的重复序列时每个BTS平均5.0个周期;bts [r14+0x8],r8
;即使对于覆盖两个相邻高速缓冲存储器线的16个独立指令的序列,其每迭代仍为相同的5个循环。