SSE 命令によるベクトル化がどのように機能するかを理解しようとしています。
ベクトル化が行われるコード スニペットを次に示します。
#include <stdlib.h>
#include <stdio.h>
#define SIZE 10000
void test1(double * restrict a, double * restrict b)
{
int i;
double *x = __builtin_assume_aligned(a, 16);
double *y = __builtin_assume_aligned(b, 16);
for (i = 0; i < SIZE; i++)
{
x[i] += y[i];
}
}
そして私のコンパイルコマンド:
gcc -std=c99 -c example1.c -O3 -S -o example1.s
アセンブラコードの出力は次のとおりです。
.file "example1.c"
.text
.p2align 4,,15
.globl test1
.type test1, @function
test1:
.LFB7:
.cfi_startproc
xorl %eax, %eax
.p2align 4,,10
.p2align 3
.L3:
movapd (%rdi,%rax), %xmm0
addpd (%rsi,%rax), %xmm0
movapd %xmm0, (%rdi,%rax)
addq $16, %rax
cmpq $80000, %rax
jne .L3
rep ret
.cfi_endproc
.LFE7:
.size test1, .-test1
.ident "GCC: (Debian 4.8.2-16) 4.8.2"
.section .note.GNU-stack,"",@progbits
私は何年も前にアセンブラーを練習してきましたが、レジスタ %rdi、%rax、および %rsi の上にあるものを知りたいです。
%xmm0 は、2 つの倍精度浮動小数点数 (16 バイト) を格納できる SIMD レジスタです。
しかし、同時追加がどのように実行されるかわかりません:
私はすべてがここで起こると思います:
movapd (%rdi,%rax), %xmm0
addpd (%rsi,%rax), %xmm0
movapd %xmm0, (%rdi,%rax)
addq $16, %rax
cmpq $80000, %rax
jne .L3
rep ret
%rax は "x" 配列を表しますか?
%rsi は C コード スニペットで何を表していますか?
最終結果 (たとえば、 a[0]=a[0]+b[0] は %rdi に格納されますか?
ご協力いただきありがとうございます