質問

制限ポインタのためのGCCによってコードの違いを見ることはできません。

ファイル1

void test (int *a, int *b, int *c)
{
  while (*a)
  {
    *c++ = *a++ + *b++; 
  }
}
.

ファイル2

void test (int *restrict a, int *restrict b, int *restrict c)
{
  while (*a)
  {
    *c++ = *a++ + *b++;
  }
}
. でコンパイルします
  gcc -S -std=c99 -masm=intel file1.c
  gcc -S -std=c99 -masm=intel file2.c
.

file1.s file2..s どちらも同じです。これはファイル名を指示する.file行を除く。

    .file   "file1.c"
    .text
    .globl  test
    .type   test, @function
test:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movq    %rdi, -8(%rbp)
    movq    %rsi, -16(%rbp)
    movq    %rdx, -24(%rbp)
    jmp .L2
.L3:
    movq    -8(%rbp), %rax
    movl    (%rax), %edx
    movq    -16(%rbp), %rax
    movl    (%rax), %eax
    addl    %eax, %edx
    movq    -24(%rbp), %rax
    movl    %edx, (%rax)
    addq    $4, -24(%rbp)
    addq    $4, -8(%rbp)
    addq    $4, -16(%rbp)
.L2:
    movq    -8(%rbp), %rax
    movl    (%rax), %eax
    testl   %eax, %eax
    jne .L3
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   test, .-test
    .ident  "GCC: (GNU) 4.6.3 20120306 (Red Hat 4.6.3-2)"
    .section    .note.GNU-stack,"",@progbits
.

これらのコードは両方ともメモリから読み取られてから、aによって指されたメモリ位置をbに割り当てます。 restrictのバージョンがabのアドレスを再読み取りせず、abのアドレスは登録内および最後にメモリに書き込まれます。

私がやっている何か問題はありますか?または、例の選択は大丈夫ですか?

私は、異なるスイッチ-O0-O1-O2-O3、GeneraCodeTagCode、および-Ofastを使用して、両方のファイルについて同じ同一の結果を得ています。

注: GCC - Version= GCC(GCC)4.6.3 20120306(Red Hat 4.6.3-2)

編集コードが変更されました。

役に立ちましたか?

解決

本は次の式です。

    *c++ = *a++ + *b++;
.

は、ポインタが各反復で変化するため、各ループ反復のすべてのポインタを参照する必要があります。restrictを使用することに利点はありません。

ループ内の線を変更してみてください。

    *c++ = *a++ + *b;
.

-O2などの最適化も可能にする必要があるかもしれません)

restrictでは、*bを1回レジスタにロードします。。

他のヒント

あなたはポインターの1つを通してのみ読み取られているので、restrictは関係ありません。

この例ポインタが同じデータをエイリアスすることがあり、データは両方のポインタを介して書き込まれて読み取られる可能性があるためです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top