4

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 に格納されますか?

ご協力いただきありがとうございます

4

2 に答える 2