At the GoingNative event, during the Interactive Panel on Day2 at the 9 minute mark, Chandler Carruth says:
Pointers create aliasing problems. They slow d
Aliasing affects performance by preventing the compiler from doing certain optimizations. For example:
void foo(int *array,int *size,int *value) {
for(int i=0;i<*size;++i) {
array[i] = 2 * *value;
}
}
Looking at this code you might expect that the compiler could load *value
once outside the loop and then set every element in the array to that value very quickly. But this isn't the case due to aliasing. Because *value
could be an alias for an element of the array it could change on any given iteration. Therefore the code has to load the value every single iteration, resulting in a potentially large slowdown.
If the variables could not alias then the above code would be equivalent to the following:
void foo(int *array,int size,int value) {
for(int i=0;i
Using LLVM's online demo to get the generated code, here are the different results:
1) With aliasing
foo: # @foo
.cfi_startproc
# BB#0:
cmpl $0, (%rsi)
jle .LBB0_3
# BB#1:
xorl %eax, %eax
.align 16, 0x90
.LBB0_2: # %.lr.ph
# =>This Inner Loop Header: Depth=1
movl (%rdx), %ecx
addl %ecx, %ecx
movl %ecx, (%rdi,%rax,4)
incq %rax
cmpl (%rsi), %eax
jl .LBB0_2
.LBB0_3: # %._crit_edge
ret
.size foo, .Ltmp1-foo
.cfi_endproc
.Leh_func_end0:
2) Without aliasing
foo: # @foo
.cfi_startproc
# BB#0:
testl %esi, %esi
jle .LBB0_3
# BB#1: # %.lr.ph
addl %edx, %edx
.align 16, 0x90
.LBB0_2: # =>This Inner Loop Header: Depth=1
movl %edx, (%rdi)
addq $4, %rdi
decl %esi
jne .LBB0_2
.LBB0_3: # %._crit_edge
ret
.size foo, .Ltmp1-foo
.cfi_endproc
.Leh_func_end0:
You can see that the version with aliasing has to do more work in the loop body (between the labels LBB0_2
and LBB0_3
).