Saturday, August 30, 2014

what is strict aliasing and pointer aliasing and use of restrict keyword


pointer aliasing:
  • Pointers alias when they point to the same address.
    • Writing via one pointer will change the value read through another.
  • The compiler often doesn’t know which pointers alias.
    • The compiler must assume that any write through a pointer may affect the value read from any another pointer!
    • So compiler will not optimize code to handle the memory correctly
Strict aliasing:
1
2
3
4
5
int foo(int *x, int *y) {
  *x = 0;
  *y = 1;
  return *x;
}
Generated code typically looks like this:
foo:    movl    $0, (%rdi)
        movl    $1, (%rsi)
        movl    (%rdi), %eax
        ret

1
2
3
4
5
int foo(int *x, long *y) {
=====> int and long pointer and so optimized
  *x = 0;
  *y = 1;
  return *x;
}
Since a pointer-to-int and a pointer-to-long may be assumed to not alias each other, the function can be compiled to return zero:

foo2:   movl    $0, (%rdi)
        xorl    %eax, %eax
        movq    $1, (%rsi)
        ret

http://www.davespace.co.uk/arm/efficient-c-for-arm/aliasing.html
http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html


restrcit:

Listing 2.1: Example of using the restrict-Keyword
1 int * aPtr ;
2 int * restrict aPtr ;


without restrict:
=================

1 void update (int *a , int *b , int * c )
2 {
3 * a += * c;
4 * b += * c;
5 }


Listing 2.3: The assembler-code to listing 2.2      (6 instructions as variable "c" loaded every time due to strict aliasing rule of c )
=================================================

1 update :
2 movl (% rdx ) , % eax
3 addl % eax , (% rdi )
4 movl (% rdx ) , % eax
5 addl % eax , (% rsi )
6 ret



void update_restrict (int *a , int *b , int * restrict c )
2 {
3 * a += * c;
4 * b += * c;
5 }


Listing 2.5: The assembler-code to listing 2.4 (only 5 instrcturions due to restrict keyword and variable "c" will not be loaded every time)
1 update_restrict :
2 movl (% rdx ) , % eax
3 addl % eax , (% rdi )
4 addl % eax , (% rsi )
5 ret


Bottom line:
=========
Due to strict alaising rules (i.e. 3 different pointers of same data type may have hold same variable's adddress in 3 pointer variable(in above example). so compiler every time will load the variable C from memory before perfomring the operations. so addtional load instruction is done in the assembly level

if we are sure that for the third variable always be unique memory then with the help of restrict keyword we can tell compiler to optimize the code. i.e no need of two load command. only one load command is sufficent.

Best reference:
https://wr.informatik.uni-hamburg.de/_media/teaching/wintersemester_2013_2014/epc-1314-fasselt-c-keywords-report.pdf


http://en.wikipedia.org/wiki/Restrict
http://www.lysator.liu.se/c/restrict.html
http://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule
http://stackoverflow.com/questions/12255686/understanding-restrict-qualifier-by-examples

According to the C language rationale document, the aliasing rules were originally made to avoid forcing compilers to always make worst-case aliasing assumptions. With the addition of the “restrict” keyword, we have a superior solution for this problem and the aliasing rules are no longer needed for that purpose.
http://blog.regehr.org/archives/959



No comments:

Post a Comment