8

制限ポインターのgccによるコードの違いはわかりません。

file1

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

file2

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.sfile2.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のアドレスを再読み取りせず、とのアドレスはレジスタ内でインクリメントされ、最後にメモリに書き込まれます。abab

私がしている何か問題はありますか?それとも、例の選択は大丈夫ですか?

異なるスイッチ、、、、、を試してみましたが、両方-O0のファイルで 同じ結果が得られました。-O1-O2-O3-Ofast-fstrict-aliasing

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

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

4

2 に答える 2

7

ポインターの 1 つだけを読んでいるだけなので、restrict問題はありません。

ポインターが同じデータに別名を付ける可能性があり、データが両方のポインターを介して書き込まれ、読み取られるため、この例を参照してください。

于 2012-10-01T20:29:11.003 に答える
3

問題は、次の式です。

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

ポインターは各反復で変化するため、とにかく各ループ反復ですべてのポインターを逆参照する必要があります。を使うメリットはありませんrestrict

ループ内の行を次のように変更してみてください。

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

( などの最適化も有効にする必要がある場合があります-O2)。

restrictレジスタに一度ロードする場合は、エイリアス*bが存在するかどうかがわからないため、制限がない場合は、各ループ反復でポインターを介してロードする必要があることがわかります。cb

于 2012-10-01T22:17:47.090 に答える