pho*_*xis 8 c pointers restrict-qualifier
对于限制指针,我看不出gcc的代码有什么不同.
文件1
void test (int *a, int *b, int *c)
{
while (*a)
{
*c++ = *a++ + *b++;
}
}
Run Code Online (Sandbox Code Playgroud)
文件2
void test (int *restrict a, int *restrict b, int *restrict c)
{
while (*a)
{
*c++ = *a++ + *b++;
}
}
Run Code Online (Sandbox Code Playgroud)
编译
gcc -S -std=c99 -masm=intel file1.c
gcc -S -std=c99 -masm=intel file2.c
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
这两种代码从存储器读出,然后分配的存储器位置所指向a到b.凡我所期望的restrict版本不会重新读取的地址a和b和的地址a和b将在注册和写入存储器结束递增.
我在做什么有什么不对吗?或者这个例子的选择还好吗?
我曾尝试用不同的开关-O0,-O1,-O2,-O3,-Ofast,并-fstrict-aliasing 与这两个文件的同一相同的结果.
注: gcc --version = gcc(GCC)4.6.3 20120306(Red Hat 4.6.3-2)
编辑代码已更改.
问题是下面的表达式:
*c++ = *a++ + *b++;
Run Code Online (Sandbox Code Playgroud)
无论如何,几乎需要在每次循环迭代中取消引用所有指针,因为指针在每次迭代中都会发生变化。使用 没有任何好处restrict。
尝试将循环内的行更改为:
*c++ = *a++ + *b;
Run Code Online (Sandbox Code Playgroud)
(您可能还需要启用优化,例如-O2)。
您会看到,在这种restrict情况下,它会加载*b到寄存器一次,而在没有限制的情况下,它需要在每次循环迭代中通过指针加载,因为它不知道是否有c别名b。