我在C中使用向量内部操作编写了一个简单的向量添加程序。这里我加载2个向量并添加它们,最后将结果向量存储回全局内存。
当我检查汇编代码时,它具有以下指令序列
movdqa 0(%rbp,%rax), %xmm7
paddd (%r12,%rax), %xmm7
movdqa %xmm7, (%rbx,%rax)
如您所见,它只将paddd
指令的一个操作数移动到寄存器(xmm7)。在paddd
指令中,第一个操作数指的是全局存储器中的地址,而不是先将寄存器移到寄存器中。
这是否意味着当paddd
执行时,它会从全局内存执行一个mov来先注册然后添加两个位于寄存器中的操作数?这相当于以下代码序列
movdqa 0(%rbp,%rax), %xmm7
movdqa 0(%r12,%rax), %xmm8
paddd %xmm8, %xmm7
movdqa %xmm7, (%rbx,%rax)
如果您需要更多可编辑程序等信息,请告诉我们,以便您自己生成程序集。
答案 0 :(得分:6)
大多数x86指令可以与内存源操作数一起使用。无需额外注册。读取 - 修改指令与加载和操作的组合一样快。优点是它需要更少的指令字节,并且不需要额外的寄存器。
在某些情况下,它还可以在英特尔CPU(uop micro-fusion)上更有效地执行。因此,如果您不希望再次需要该内存地址的数据,请更喜欢将负载折叠到其他指令中。
有关CPU内部的文档,以及如何优化asm和C代码,请参阅http://agner.org/optimize/。