C/C++关键字之restrict
C/C++关键字之restrict
在C语言中,restrict关键字用于修饰指针(C99标准)。通过加上restrict关键字,程序员可提示编译器:在该指针的生命周期内,其指向的对象不会被别的指针所引用。
需要注意的是,在C++中,并无明确统一的标准支持restrict关键字。但是很多编译器实现了功能相同的关键字,例如gcc和clang中的__restrict关键字。
1 |
|
add1函数的返回值会永远是10 + 12 = 22吗?
答案是不一定。在指针a和b的地址不同时,返回22没有问题。但是当指针a与b指向的是同一个int对象时,该对象先被赋值为10,后被赋值为12,因此a和b都返回12,因此add1函数最终返回24。
下面是一个简单的例子:
1 |
|
程序输出:
1 |
|
开启-O3优化,add1对应的汇编代码如下:
为了得到*a
的值访问了1次内存,而不管在何种条件下(a == b
or a != b
),*b
的值都是12。因此编译器将*a
的值载入eax
寄存器后,直接加上立即数12,而无需再访问内存获取*b
的值。在无法确定指针a和b是否相同的情况下,编译器只能帮你优化到这里了。
1 |
|
加上了restrict关键字过后,同样开启-O3优化,add1对应的汇编代码如下:
加上关键字restrict后,编译器能够确认指针a和b不可能指向同一个内存地址,因此在求*a + *b时,无虚访问内存,因为*a必然等于立即数10,*b必然等于立即数12。
1 |
|
有无restrict关键字的两种情况下的汇编指令可看到,后者比前者少访问一次内存,且少执行一条指令。就是因为没加restruct关键字时,编译器不能确定别的地方是不是会修改此值,所以会去相应的地址查看。
这样当我们明确知道两个指针不可能指向同一个地址时,我们就可以通过使用restrict关键字来进行性能优化。
注意使用restrict的时候,程序员必须确保不会出现pointer aliasing,即同一块内存无法通过两个或以上的指针变量名访问。不满足这个条件强行指定restrict,将会出现underfined behavior。
通常编写代码时会忽略pointer aliasing的问题。更常见是在性能分析时,通过反汇编看到很多冗余的读取指令,才会想到加入restrict关键字来提升性能。
参考资料
C/C++关键字之restrict - 知乎 (zhihu.com)
restrict type qualifier - cppreference.com
如何理解C语言关键字restrict? - 知乎 (zhihu.com)
(65条消息) 关键字_restrict___restrict_楚楚可薇的博客-CSDN博客
(65条消息) 【C++】关键字restrict的作用_restrict关键字的作用_不知所措的渣渣辉的博客-CSDN博客
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!