合理使用restrict
【说明】 在保证多个指针所指向的区域无交叠的前提下,可以将这些指针加上restrict限定符,用于指导编译器做出更激进的优化。
【原理】restrict 关键字是C语言中的一种类型限定符(Type Qualifiers),只用于限定指针,该关键字用于告诉编译器,所有修改该指针指向内容的操作,全部是基于该指针的,即不存在其他修改操作的途径,消除pointer aliasing(指针别名),从而帮助编译器生成更优的机器码。
需要特别注意的是,如果指针指向同一块区域而错误的加上了restrict限定符,则结果是未定义的。
【注意事项】 不涉及
【案例】
优化前:
int g_test;
int testRestrict(int *a, int *b)
{
*a = g_test;
*b += 2;
*a += 1;
return *a + *b;
}
对应的汇编如下:
testRestrict(int*, int*):
ldr r3, .L3
ldr r3, [r3]
str r3, [r0] // 由于无法假设a和b的地址不重叠,对a赋值之后,在load b之前要store a
ldr r3, [r1]
add r3, r3, #2
str r3, [r1]
ldr r3, [r0] // 由于b的修改可能影响a,这里会再load一次a
add r3, r3, #1
str r3, [r0]
ldr r0, [r1] // 由于a的修改可能影响b,这里会再load一次b
add r0, r3, r0
bx lr
.L3:
.word .LANCHOR0
g_test:
优化后:
int g_test;
int testRestrict(int *__restrict a, int *__restrict b)
{
*a = g_test;
*b += 2;
*a += 1;
return *a + *b;
}
对应的汇编:
testRestrict(int*, int*):
ldr r3, .L3
ldr r2, [r1]
ldr r3, [r3]
add r2, r2, #2
add r3, r3, #1
str r3, [r0]
str r2, [r1]
add r0, r2, r3
bx lr
.L3:
.word .LANCHOR0
g_test:
说明:对比可以看出,相比没有加restrict修饰,省了3条汇编指令。
父主题: 函数使用