今天在写opencl的kernel端代码时用到了restrict关键字,做个记录。

restrict限定符的作用

C语言中的一种类型限定符,用于告诉编译器,对象已经被指针所引用,不能通过除去该指针以外的所有其他直接或间接的方式修改该对象的内容

restrict限定符的用法

restrict关键字允许编译器优化某部分代码以更好地支持计算。它只能用于指针,表明该指针是访问该对象唯一且初始的方式。要弄明白为什么这样做有用,先看几个例子。考虑下面的代码:

int ar[10];
int * restrict restar= (int *) malloc(10 * sizeof(int));
int * par= ar;

这里,指针restar是访问由malloc()所分配的内存的唯一且初始的方式。因此,可以用restrict关键字限定它。而指针par既不是访问ar数组中数据的初始方式,也不是唯一方式。所以不用把它设置成restrict。

现在考虑下面稍微复杂的例子,其中n是int类型:

for (n=0; n<10; n++){par[n]+=5;restar[n] +=5;ar[n] *=2;par[n] +=3;restar[n] +=3;}

由于之前声明了restar是访问它所指向的数据块的唯一且初始的方式,编译器可以把涉及restar的两条语句替换成下面的语句,效果相同:

restar[n] +=8;/*可以进行替换*/

但是,如果把与par相关的两条语句替换成下面的语句,将导致计算错误:

par[n] +=8;/*将给出错误的结果*/

这是因为for循环在par两次访问相同的数据之间,用ar改变了该数据的值。

在本例中,如果未使用restrict关键字,编译器必须假定最坏的情况(即,两次使用指针之间,其他的标识符可能已经改变了该数据)。如果用了restrict关键字,编译器就可以选择捷径优化计算

restrict限定符还可以用于函数形参中的指针。这意味着编译器可以假定该函数体内其他标识符不会修改该指针指向的数据,而且编译器可以尝试对其优化,使其不做别的用途。例如,C库有两个函数用于把一个位置上的字节拷贝到另一个位置。在C99中,这两个函数的原型是:

void * memcpy(void * restrict s1, const void * restrict s2, size_t n);
void *memmove(void * s1, const void * s2,size_t n);

这两个函数都从位置s2把n个字节拷贝到位置s1。memcpy()函数要求两个位置不重叠,但是memove()没有这样的要求。声明s1和s2为restrict说明这两个指针是访问相应数据的唯一方式,所以它们不能访问相同块的数据。这满足memcpy()函数无重叠的要去。memmove()允许重叠,它在拷贝数据时不得不更小心,以防止在使用数据之前就先覆盖了数据

总结

restrict关键字有两个读者。一个是编译器,该关键字告诉编译器可以自由假定一些优化方案。另一个读者是用户,该关键字告知用户要使用满足restrict要求的参数,总而言之,编译器不会检查用户是否遵循这一限制,但是无是它可能产生严重后果。

C语言中的restrict限定符相关推荐

  1. 一文理解C语言中的volatile修饰符

    一文理解C语言中的volatile修饰符 2019/12/2 FesianXu 前言 volatile修饰符是在嵌入式开发和多线程并发编程中常见的修饰符,理解其对于实践过程非常有帮助,此文参考了[1] ...

  2. 整理 Go 语言中 20 个占位符!

    学到什么 什么是占位符? 哪些函数支持? 如何使用占位符? 不同的占位符的作用? 配合占位符的几个标记符号用法? 概念 什么是占位符?你就从表面意思理解,就是占位置,只不过有很多不同种类的位置,而且这 ...

  3. c语言restrict和const,C语言中const、volatile、restrict等类型限定符的区别

    auto.register.static.extern是属于存储类修饰符.在声明时,存储类修饰符最多只能使用一个,而且无法用在typeof声明中. 而类型限定符是指const.volatile.res ...

  4. C语言中restrict的意义,restrict关键字在C ++中的含义是什么?

    正如其他人所说,如果C ++ 14中没有任何意义,那么让我们考虑一下__restrict__与C99相同的GCC扩展restrict. C99 restrict说两个指针不能指向重叠的内存区域.最常见 ...

  5. C语言中extern修饰符的用法

    在C语言中,修饰符extern用在变量或者函数的声明前,用来说明"此变量/函数是在别处定义的,要在此处引用". 0. extern修饰变量的声明.举例来说,如果文件a.c需要引用b ...

  6. 【重温经典C语言】~c语言中%x、%c、%d、%x等等等、c语言取地址符的作用、C语言中的 联合体

    本章目录: 1. c语言中%x.%c.%d.%x等等等 2. c语言取地址符&的作用 3. 了解 C语言中的 联合体 3.1 什么是联合体? 3.2 定义 3.2.1 举例 3.3 初始化联合 ...

  7. C语言中的类型限定符.const限定符

    目录 1.1const限定符 1.1.1const限定符修饰普通对象 1.1.2const限定符修饰数组元素 1.1.3const限定符修饰指针类型对象 1.1.4const限定符修饰函数形参类型为数 ...

  8. 【✊基础不牢,地动山摇のC语言中static关键字✊】

    C语言中static关键字 用static声明限定外部变量与函数,可以将其后声明的对象的作用域限定为被编译源文件的剩余部分.要降对象指定为静态存储,可以在正常的声明之前加上关键字static作为前缀. ...

  9. C语言中const的用法

    C语言中const的用法 基本解释         const是一个C语言的关键字,它限定一个变量不允许被改变.使用const在一定程度上可以提高程序的健壮性,另外,在观看别人代码的时候,清晰理解co ...

最新文章

  1. 启动tomcat报StandardServer.await: create[8005] 故障解决
  2. Spring MVC笔记 添加错误页面
  3. js-比较两个日期的大小
  4. 15 - java 继承
  5. 【英语学习】【WOTD】mirandize 释义/词源/示例
  6. java有常函数_Java开发笔记(十一)常见的数学函数
  7. JSP指令、动作和对象
  8. cisco fabricpath 功能介绍
  9. Python中文文本分句 sentence tokenize
  10. 【网络--实验】华三防火墙命令行调试实例
  11. html中div是什么意思
  12. Android招聘心得分享
  13. 敏捷宣言的内容及准则
  14. 市面上常用的语音识别模块主要包含哪些组件?
  15. GDAL C++ API 学习之路 (1)Driver篇 代码示例 翻译 自学
  16. AEJoy —— 表达式之无缝循环摆/扭动【JS】
  17. 免费学习网站-中国大学mooc
  18. 有线网络硬件接口简介
  19. 第一部分——简单句——第二章——简单句的核心——第二节 成分角度的扩展非谓语动词作定语、状语
  20. 启明云端分享:1.54寸彩屏与按摩椅的智慧碰撞

热门文章

  1. SSCNet环境搭建
  2. Linux-hostname查看及修改
  3. 移动端H5页面生成图片解决方案
  4. java全角空格转换半角空格
  5. 在线博客系统——获取用户信息,退出登录
  6. 服装检索相关论文阅读
  7. Virustotal威胁猎捕
  8. 我也来读jquery
  9. 2K Star!超过 50 个专题、450 个好项目,大半年来推荐过的重磅项目合集
  10. android 音频显示器,安卓手机投屏(带声音同步)教程