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
Loops x86_64-程序集-循环条件和故障 我不是在要求一个基准。_Loops_Assembly_Conditional Statements_X86 64 - Fatal编程技术网

Loops x86_64-程序集-循环条件和故障 我不是在要求一个基准。

Loops x86_64-程序集-循环条件和故障 我不是在要求一个基准。,loops,assembly,conditional-statements,x86-64,Loops,Assembly,Conditional Statements,X86 64,(如果是这样的话,我会自己做的。) 我的问题: 为了方便起见,我倾向于避免使用间接/索引寻址模式 作为替代,我经常使用立即寻址、绝对寻址或寄存器寻址 守则: ; %esi has the array address. Say we iterate a doubleword (4bytes) array. ; %ecx is the array elements count (0x98767) myloop: ... ;do whatever with %esi add $4,

(如果是这样的话,我会自己做的。)


我的问题:

为了方便起见,我倾向于避免使用间接/索引寻址模式

作为替代,我经常使用立即寻址、绝对寻址或寄存器寻址

守则:

; %esi has the array address. Say we iterate a doubleword (4bytes) array.
; %ecx is the array elements count
(0x98767) myloop:
    ... ;do whatever with %esi
    add $4, %esi
    dec %ecx
    jnz 0x98767;
在这里,我们有一个序列化组合(dec和jnz),它可以防止正确的无序执行(依赖)


有没有办法避免这种情况/打破dep?(我不是汇编专家)。

为英特尔CPU进行优化时,始终将标志设置指令放在条件跳转指令之前(如果它是下表中列出的简单指令之一),以便它们可以在解码器中宏融合到一个uop中

对于不进行宏融合的旧CPU来说,这样做并没有明显的问题。较早地设置标志可能会将此类CPU的分支预测失误惩罚缩短1,但无序执行意味着较早地移动
dec
两条指令不会产生真正的区别。另见。为了真正发挥作用,您可以展开循环和/或在可以更简单地计算的对象上执行分支,理想情况下不依赖于缓慢的输入,因此OoO exec可以在处理循环体的较旧迭代时解决分支。i、 e.回路计数器dep链可以在主工作之前运行

我没有基准测试,但我不认为越来越少的CPU的一个小缺点可以证明错过了进行融合的CPU的前端吞吐量优势(解码和发布)。uop总吞吐量通常是一个瓶颈

AMD推土机/打桩机/蒸汽压路机可以将
test/cmp
与任何
jcc
进行融合,但只能将
test/cmp
与任何其他ALU指令进行融合。因此,与分支机构相比,放在这里是绝对正确的。如果英特尔CPU能够在sandybridge系列上进行宏融合,那么将其他东西与分支放在一起仍然是很有价值的

来自Microach指南,表9.2(适用于Sandybridge/Ivybridge):

因此,基本上,
inc/dec
可以与
jcc
进行宏融合,只要条件仅取决于由
inc/dec
修改的位

(否则,它们不会进行宏融合,您会插入一个额外的uop来合并标志(比如在写入
al
后读取
eax
),或者在早期的CPU上,部分标志会暂停。)

Core2/Nehalem的宏融合能力更有限(仅用于CMP/测试,JCC组合更有限),Core2根本无法在64位模式下进行宏融合


如果您还没有阅读Agner Fog的优化asm和C指南,也可以阅读。它们充满了必要的知识。

让我直截了当地说:你想要一个条件跳转,它取决于上一条指令的结果,可以按照该指令的顺序执行吗?我认为这在逻辑上是不可能的。另外请注意,不建议使用
dec
,因为它会导致部分标志更新暂停。@Jester:那么我应该使用sub?您可以使用
lea4(%esi),%esi
进行添加,而这不会影响标志,因此您可以在更高的位置插入
subl$1,%ecx
。正如@davmac所说,除非你使用
循环
指令,否则你无法摆脱依赖性,这也是不推荐的。如果可能的话,一定要展开循环,以分摊循环开销的成本。非常感谢Peter,我已经从他那里得到了“指令表”和“优化汇编”。虽然我没有完全阅读后者(因此我无知),但我现在就去读。谢谢彼得:)@Kroma:这张表来自microarchitecture.pdf。我忘了他是否在《优化asm指南》中提到过宏融合,但可能至少提到了它。可能值得一提的是,第一条指令和第二条指令必须在同一个16字节的解码段中才能工作(具有相同的地址,四舍五入到16字节)。想想Agner Fog在什么地方提到过这个。@Noah:首先,解码组并不总是对齐的。第二,Sandybridge系列保留组中的最后一条指令(如果它是融合候选指令),以防下一组中的第一条指令是分支。(因此,它牺牲了一些传统的解码吞吐量,以构建更紧凑的uop缓存线,并可能最大限度地减少ROB空间和其他后端资源消耗)。我想这已经在某个地方讨论过了,但没有具体的想法。不过,你可能会在谷歌上找到一些东西。
First       | can pair with these  |  cannot pair with
instruction | (and the inverse)    |
---------------------------------------------
cmp         |jz, jc, jb, ja, jl, jg|   js, jp, jo
add, sub    |jz, jc, jb, ja, jl, jg|   js, jp, jo
adc, sbb    |none                  |
inc, dec    |jz, jl, jg            |   jc, jb, ja, js, jp, jo
test        | all                  |
and         | all                  |
or, xor, not, neg | none           |
shift, rotate     | none           |

Table 9.2. Instruction fusion