I am trying to understand the effect of using restrict keyword over arrays defined inside the same struct. When I compare the assembly code for cases with and without restrict pointer, I see no difference. My code "test_res.c" is:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <limits.h>
typedef struct
{
int index;
int index2;
double *restrict a;
double *restrict b;
double *restrict c;
} matstruct;
void finalVal (matstruct *m)
{
int i,j;
for (j=0; j<m->index2; j++){
for (i= 0; i<m->index; i++){
m->b[i] = sqrt(m->a[i]) * sqrt(m->b[i]);
m->c[i] = sqrt(m->a[i]) + sqrt(m->b[i]);
m->c[i] += sqrt(m->a[i]) * sqrt(m->b[i]);
}
}
}
int main()
{
matstruct *m = malloc (sizeof(matstruct));
m->index = 100000;
m->index2 = 10000;
m->a = malloc (sizeof(double)*(m->index));
m->b = malloc (sizeof(double)*(m->index));
m->c = malloc (sizeof(double)*(m->index));
for (int i=0; i<m->index; i++){
m->a[i] = 10.0+i;
m->b[i] = 20.0+i;
m->c[i] = 30.0+i;
}
finalVal (m);
free (m->a);
free (m->b);
free (m->c);
free (m);
return 0;
}
I use the following steps to get assembly code:
- gcc -g -O3 -c test_res.c
- objdump -S test_res.o > test_res.s
Now, remove the "restrict" keyword from the code and create another assembly code "test_no_res.s" using above steps. Finally, compare the two assembly codes. There seems no difference.
So, does it mean that using the "restrict" keyword inside the structure has no effect ?
restrict
only matters in case of "pointer aliasing" optimizations. That is, cases where the compiler cannot be sure if two pointers pointing at something outside the current function or translation unit point at the same memory location or not. In case there is a risk of them doing so, the compiler might have to make additional copies of the pointed-at data etc.restrict
is a contract between the programmer and the compiler, where the programmer swears "I promise that the data pointed at is only ever accessed through this very pointer, and it is not pointing at some global variable either".In your code, it doesn't really matter where the individual pointers a,b,c point. The compiler just needs to grab whatever they point at, copy it and pass it to
sqrt
. So there's no obvious reason whyrestrict
would matter here.Giving an example where
restrict
matters based on your code proved hard, neither gcc nor clang seem smart enough to take advantage of it in this specific case. Better examples here: https://stackoverflow.com/a/75854539/584518