制限付きポインタの効果がないのはなぜですか
-
12-12-2019 - |
質問
制限ポインタのための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
のバージョンがa
とb
のアドレスを再読み取りせず、a
とb
のアドレスは登録内および最後にメモリに書き込まれます。
私がやっている何か問題はありますか?または、例の選択は大丈夫ですか?
私は、異なるスイッチ-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
は関係ありません。
この例ポインタが同じデータをエイリアスすることがあり、データは両方のポインタを介して書き込まれて読み取られる可能性があるためです。