我有一个看起来像这样的Java循环:
public void testMethod() {
int[] nums = new int[10];
for (int i = 0; i < nums.length; i++) {
nums[i] = 0x42;
}
}
我得到的程序集是这样的:
0x00000001296ac845: cmp %r10d,%ebp
0x00000001296ac848: jae 0x00000001296ac8b4
0x00000001296ac84a: movl $0x42,0x10(%rbx,%rbp,4)
0x00000001296ac852: inc %ebp
0x00000001296ac854: cmp %r11d,%ebp
0x00000001296ac857: jl 0x00000001296ac845
0x00000001296ac859: mov %r10d,%r8d
0x00000001296ac85c: add $0xfffffffd,%r8d
0x00000001296ac860: mov $0x80000000,%r9d
0x00000001296ac866: cmp %r8d,%r10d
0x00000001296ac869: cmovl %r9d,%r8d
0x00000001296ac86d: cmp %r8d,%ebp
0x00000001296ac870: jge 0x00000001296ac88e
0x00000001296ac872: vmovq -0xda(%rip),%xmm0
0x00000001296ac87a: vpunpcklqdq %xmm0,%xmm0,%xmm0
0x00000001296ac87e: xchg %ax,%ax
0x00000001296ac880: vmovdqu %xmm0,0x10(%rbx,%rbp,4)
0x00000001296ac886: add $0x4,%ebp
0x00000001296ac889: cmp %r8d,%ebp
0x00000001296ac88c: jl 0x00000001296ac880
如果我的理解是正确的,则汇编的第一块是
nums[i] = 0x42;
。在第三块中,有一个vmovdqu
vmovdqu指令将值从整数向量移动到未对齐的内存位置。
但是,我仍然不完全了解我的循环上下文中的
vmovdqu
在做什么。汇编代码的第三部分到底在做什么?
完整的代码可以在这里找到:https://pastebin.com/cT5cJcMS
最佳答案
优化器已选择对您的循环进行矢量化处理,每个“迭代”设置4个值。 (vmovdqu
之前的指令相当不透明,但是大概是将0x42
放入XMM0
的所有通道中。)“unaligned”变体是必需的,因为不能保证数组在内存中是SIMD对齐的(毕竟,它存储int32
s ,而不是int32x4
)。