В первом примере компилятор успешно векторизовал цикл:
struct Word
{
int a;
int b;
int c;
int d;
};
size_t N = 1'000'000'000;
Word * words = new Word[N];
for (size_t i = 0; i < N; ++i)
{
words[i].a = value + 1;
words[i].b = value + 2;
words[i].c = value + 3;
words[i].d = value + 4;
}
Тело цикла:
=> 0x0000000000404c40 <+96>: movdqu %xmm0,-0x70(%rdi)
0x0000000000404c45 <+101>: movdqu %xmm0,-0x60(%rdi)
0x0000000000404c4a <+106>: movdqu %xmm0,-0x50(%rdi)
0x0000000000404c4f <+111>: movdqu %xmm0,-0x40(%rdi)
0x0000000000404c54 <+116>: movdqu %xmm0,-0x30(%rdi)
0x0000000000404c59 <+121>: movdqu %xmm0,-0x20(%rdi)
0x0000000000404c5e <+126>: movdqu %xmm0,-0x10(%rdi)
0x0000000000404c63 <+131>: movdqu %xmm0,(%rdi)
0x0000000000404c67 <+135>: add $0x8,%rsi
0x0000000000404c6b <+139>: sub $0xffffffffffffff80,%rdi
0x0000000000404c6f <+143>: cmp %rsi,%rdx
0x0000000000404c72 <+146>: jne 0x404c40 <run()+96>
А вот во втором, где происходит то же самое, но Word разделилась на 2 части и теперь 2 массива - нет:
struct Word
{
int a;
int b;
};
struct Half
{
int c;
int d;
};
size_t N = 1'000'000'000;
Word * words = new Word[N];
Half * halfs = new Half[N];
for (size_t i = 0; i < N; ++i)
{
words[i].a = value + 1;
words[i].b = value + 2;
halfs[i].c = value + 3;
halfs[i].d = value + 4;
}
Тело цикла:
=> 0x0000000000404c50 <+96>: mov %r9d,(%rsi,%rdx,8)
0x0000000000404c54 <+100>: mov %edi,0x4(%rsi,%rdx,8)
0x0000000000404c58 <+104>: mov %ebx,(%rcx,%rdx,8)
0x0000000000404c5b <+107>: mov %eax,0x4(%rcx,%rdx,8)
0x0000000000404c5f <+111>: mov %r9d,0x8(%rsi,%rdx,8)
0x0000000000404c64 <+116>: mov %edi,0xc(%rsi,%rdx,8)
0x0000000000404c68 <+120>: mov %ebx,0x8(%rcx,%rdx,8)
0x0000000000404c6c <+124>: mov %eax,0xc(%rcx,%rdx,8)
0x0000000000404c70 <+128>: add $0x2,%rdx
0x0000000000404c74 <+132>: cmp %rdx,%r10
0x0000000000404c77 <+135>: jne 0x404c50 <run()+96>