Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 内存目标BTS怎么会比load/BTS reg、reg/store慢得多?_Performance_Assembly_X86 64_Cpu Architecture_Microcoding - Fatal编程技术网

Performance 内存目标BTS怎么会比load/BTS reg、reg/store慢得多?

Performance 内存目标BTS怎么会比load/BTS reg、reg/store慢得多?,performance,assembly,x86-64,cpu-architecture,microcoding,Performance,Assembly,X86 64,Cpu Architecture,Microcoding,在一般情况下,使用内存操作数时,可以占用内存或寄存器操作数的指令如何比mov+mov->instruction->mov+mov慢 基于中发现的吞吐量和延迟(查看我的案例中的Skylake,第238页) 我看到btr/bts说明的以下数字: instruction, operands, uops fused domain, uops unfused domain, latency, throughput mov r,r 1 1

在一般情况下,使用内存操作数时,可以占用内存或寄存器操作数的指令如何比mov+mov->instruction->mov+mov慢

基于中发现的吞吐量和延迟(查看我的案例中的Skylake,第238页) 我看到
btr/bts
说明的以下数字:

instruction, operands, uops fused domain, uops unfused domain, latency, throughput
mov          r,r       1                  1                    0-1      .25
mov          m,r       1                  2                    2        1
mov          r,m       1                  1                    2        .5
... 
bts/btr      r,r       1                  1                    N/A      .5
bts/btr      m,r       10                 10                   N/A      5
我不明白这些数字怎么可能是正确的。即使在最坏的情况下,如果没有备用寄存器,并且您已将一个寄存器存储在临时内存位置,则执行以下操作会更快:

## hypothetical worst-case microcode that saves/restores a scratch register
mov m,r  // + 1  throughput , save a register
mov r,m  // + .5 throughput , load BTS destination operand
bts r,r  // + 1  throughput , do bts (or btr)
mov m,r  // + 1  throughput , store result
mov r,m  // + .5 throughput , restore register
作为最坏的情况,这比仅仅
bts m,r
(4<5)具有更好的吞吐量。(编辑注意:当吞吐量有不同瓶颈时,增加吞吐量是不起作用的。您需要考虑UOPS和端口;这个序列应该是2C吞吐量,在1 /时钟存储吞吐量上受到限制)

微码指令有自己的寄存器集,所以看起来不太可能真的需要它。有人能解释一下为什么bts(或一般任何指令)在内存、寄存器操作数方面比使用最坏情况下的移动策略具有更高的吞吐量吗


(编者按:是的,微码可以使用一些隐藏的临时寄存器。像
add[mem],reg
这样的东西至少在逻辑上只是加载到其中一个寄存器中,然后存储结果。)

您缺少的是,当使用内存操作数时,BT、BTC、BTS和BTR的工作方式与您描述的不同。您假设内存版本与寄存器版本的工作方式相同,但事实并非如此。对于寄存器版本,使用的第二个操作数的值取模64(或16或32)。对于内存版本,第二个操作数的值按原样使用。这意味着指令访问的实际内存位置可能不是内存操作数给定的地址,而是它的某个位置

例如,忽略保存寄存器和原子性的需要,要使用BTS的寄存器版本获得与
BTS[rsi+rdi]相同的操作,rax
,您需要执行以下操作:

LEA rbx, [rsi + rdi]
MOV rcx, rax
SHR rcx, 8
MOV rdx, [rbx + rcx]
BTS rdx, rax
MOV [rbx + rcx], rdx

如果知道RAX的值小于64,或者它是一个更简单的内存操作数,则可以简化此操作。事实上,正如您所注意到的,在这种情况下,使用更快的寄存器版本可能比使用较慢的内存版本更有利,即使这意味着需要更多的指令。

请注意位字符串指令的疯狂CISC语义;它们可以在寻址模式寻址的dword之外建立索引!!这就是它的特殊之处。您的模拟似乎基于AT&T语法,目标是最后一个。Agner的表是Intel语法,目标优先。Skylake有2/时钟加载,1/时钟存储,反之亦然(希望您能意识到这更有意义)。我建议您在示例中使用Intel语法来保存regs,即交换前2行的顺序和注释的perf部分,等等。我为您修复了这一点,并就您的假设留下了一些注释。现在请锁定bts[rsi+rdi],rax:-)(这是我用过的唯一一种。)@prl啊,我知道我忘了什么。谢谢