I can't see any difference of code by gcc for restrict pointers.
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++;
}
}
compile with
gcc -S -std=c99 -masm=intel file1.c
gcc -S -std=c99 -masm=intel file2.c
file1.s and file2.s both are same, except the .file
line, which tells the filename:
.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
Both of these code read from the memory and then assign the memory location pointed to by a
to b
. Where i expected the restrict
version will not re-read the addresses of a
and b
, and the addresses of a
and b
will be incremented in-register and at the end written to memory.
Is there anything wrong i am doing? Or is the selection of the example okay?
I have tried with different switches -O0
, -O1
, -O2
, -O3
, -Ofast
, and -fstrict-aliasing
with the same identical results for both of the files.
Note: gcc --version = gcc (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2)
EDIT Code changed.
It has nothing to do with C++ because it's not a keyword or feature of C++, and if you use C header files in C++ you must remove the restrict keyword. Of course if you pass aliased pointers to a C function that declares them restricted (which you can do from either C++ or C) then it's undefined, but that's on you.
In the C programming language, restrict is a keyword, introduced by the C99 standard, that can be used in pointer declarations. By adding this type qualifier, a programmer hints to the compiler that for the lifetime of the pointer, no other pointer will be used to access the object to which it points.
restrict is not supported by C++. It is a C only keyword.
You are only reading through one of the pointers, so restrict
doesn't matter.
See this example where it does matter because the pointers may alias the same data, and the data are written and read through both pointers.
The thing is that the following expression:
*c++ = *a++ + *b++;
pretty much needs to dereference all the pointers in each loop iteration anyway, since the pointers change in each iteration. There's no benefit to using restrict
.
Try changing the line inside the loop to:
*c++ = *a++ + *b;
(you may need to also enable optimizations such as -O2
).
You'll see that in the restrict
case it loads *b
into a register once, while in the case without restrict it needs to load through the pointer in each loop iteration because it doesn't know whether or not c
ever aliases b
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With