C/C++语言中的restrict关键字

编程入门 行业动态 更新时间:2024-10-28 20:26:26

C/C++语言中的restrict<a href=https://www.elefans.com/category/jswz/34/1769821.html style=关键字"/>

C/C++语言中的restrict关键字

在C语言中,restrict关键字用于修饰指针(C99标准)。通过加上restrict关键字,编程者可提示编译器:在该指针的生命周期内,其指向的对象不会被别的指针所引用。

使用此关键字,将允许编译器预知多个指针之间的相互独立性,从而允许编译器做更加激进的优化。例如[1]:

int add(int *a, int *b){*a = 10;*b = 12;return *a + *b;
}

在这个函数中,有的同学就说了,直接返回22不就好了,这么想的同学就忽略了a==b的可能,如果a和b指向同一个地址,那么这个函数将返回24。实际上,编译器就是这个想要把额外操作去掉的“同学”,如果我们能清晰的告诉他,a和b在本函数中不管怎么移动都永远不可能指向相同的地址,那么,处理这个函数时,*a + *b 可以直接使用两立即数相加,不需要再从地址中读取值,就能优化代码执行的效率。

因此,在没有指明a不可能等于b的情况下,编译器能做到的最大优化就是,b指向地址的值一定是12,但a的值必须从地址中读取。

-O3
0000000000400a10 <_Z4add1PiS_>:400a10:   c7 07 0a 00 00 00       movl   $0xa,(%rdi) ; *a = 10400a16:   c7 06 0c 00 00 00       movl   $0xc,(%rsi) ; *b = 10400a1c:   8b 07                   mov    (%rdi),%eax ; 结果 = *a400a1e:   83 c0 0c                add    $0xc,%eax   ; 结果 += 12 400a21:   c3                      retq

上面400a1c地址指令,读a。

于是我们可以使用restrict关键字告诉编译器,你放心优化,传入的指针a和指针b一定不指向同一个地址。

int add(int __restrict *a, int __restrict *b){*a = 10;*b = 12;return *a + *b;
}

那么编译器就顿悟了,知道a中的内容一定是10,b中的内容一定是12,a也不需要读。

0000000000400a30 <_Z4add2PiS_>:400a30:   c7 07 0a 00 00 00       movl   $0xa,(%rdi) ; *a = 10400a36:   b8 16 00 00 00          mov    $0x16,%eax  ; 结果 = 22400a3b:   c7 06 0c 00 00 00       movl   $0xc,(%rsi) ; *b = 12400a41:   c3                      retq

于是编译后的代码直接采用立即数寻址的方式完成这个函数。整体上又比上一次优化中,少了一条指令。别看仅仅少了一条指令,在性能上,我们将两者分别执行1亿次,后者仅耗费了56ns,而前者耗费了146ns [1],性能上接近为后者的1/3。

[1] 

更多推荐

C/C++语言中的restrict关键字

本文发布于:2023-11-15 15:18:58,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1601852.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:关键字   语言   restrict

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!