C语言

C语言关键字RESTRICT介绍

时间:2023-10-25 16:00:12 美云 C语言 我要投稿
  • 相关推荐

C语言关键字RESTRICT介绍

  学习C语言也有好长时间了,相信大家在学习C语言的过程中也都有所收获,不过,也应该遇到了许多问题。今天小编在这里就帮同学们介绍一下怎么了解restrict这个词。

  C语言关键字RESTRICT介绍

  要理解 restrict,先要知道什么是 Pointer aliasing。

  Pointer aliasing 是指两个或以上的指针指向同一数据,例如

  int i = 0;

  int *a = &i;

  int *b = &i;

  这样会有什么问题呢?

  如果编译器采用最安全的假设,即不理会两个指针会否指向同一数据,那么通过指针读写数据是很直观的。

  然而,这种假设会令编译器无法优化,例如:

  int foo(int *a, int *b)

  {

  *a = 5;

  *b = 6;

  return *a + *b; // 不一定是 11!

  }

  如果 a 和 b 都指向同一数据,*b = 6 会导致 *a = 6,返回12。所以编译器在做 *a + *b 的时候,需要重新读取 *a 指向的数据:

  foo:

  movl $5, (%rdi) # 存储 5 至 *a

  movl $6, (%rsi) # 存储 6 至 *b

  movl (%rdi), %eax # 重新读取 *a (因为有可能被上一行指令造成改变)

  addl $6, %eax # 加上 6

  ret

  如果我们确保两个指针不指向同一数据,就可以用 restrict 修饰指针类型:

  int rfoo(int *restrict a, int *restrict b)

  {

  *a = 5;

  *b = 6;

  return *a + *b;

  }

  编译器就可以根据这个信息,做出优化:

  rfoo:

  movl $11, %eax # 在编译期已计算出 11

  movl $5, (%rdi) # 存储 5 至 *a

  movl $6, (%rsi) # 存储 6 至 *b

  ret

  但如果用了 restrict 去修饰两个指针,而它们在作用域内又指向同一地址,那么是未定义行为。

  总括而言,restrict 是为了告诉编译器额外信息(两个指针不指向同一数据),从而生成更优化的机器码。注意,编译器是无法自行在编译期检测两个指针是否 alias。如使用 restrict,程序员也要遵守契约才能得出正确的代码(指针不能指向相同数据)。

  以个人经验而言,编写代码时通常会忽略 pointer aliasing 的问题。更常见是在性能剖测时,通过反编译看到很多冗余的读取指令,才会想到加入 restrict 关键字来提升性能。

  RESTRICT简介

  restrict是c99标准引入的,它只可以用于限定和约束指针,并表明指针是访问一个数据对象的唯一且初始的方式。即它告诉编译器,所有修改该指针所指向内存中内容的操作都必须通过该指针来修改,而不能通过其它途径(其它变量或指针)来修改;这样做的好处是,能帮助编译器进行更好的优化代码,生成更有效率的汇编代码。如 int *restrict ptr, ptr 指向的内存单元只能被 ptr 访问到,任何同样指向这个内存单元的其他指针都是未定义的,直白点就是无效指针。restrict 的出现是因为 C 语言本身固有的缺陷,C 程序员应当主动地规避这个缺陷,而编译器也会很配合地优化你的代码。

  RESTRICT应用

  C库中有两个函数可以从一个位置把字节复制到另一个位置。在C99标准下,它们的原型如下:

  void * memcpy(void * restrict s1, const void * restrict s2,size_tn);

  void * memmove(void * s1, const void * s2,size_tn);

  这两个函数均从s2指向的位置复制n字节数据到s1指向的位置,且均返回s1的值。两者之间的差别由关键字restrict造成,即memcpy()可以假定两个内存区域没有重叠。memmove()函数则不做这个假定,因此,复制过程类似于首先将所有字节复制到一个临时缓冲区,然后再复制到最终目的地。如果两个区域存在重叠时使用memcpy()会怎样?其行为是不可预知的,既可以正常工作,也可能失败。在不应该使用memcpy()时,编译器不会禁止使用memcpy()。因此,使用memcpy()时,您必须确保没有重叠区域。这是程序员的任务的一部分。

  关键字restrict有两个读者。一个是编译器,它告诉编译器可以自由地做一些有关优化的假定。另一个读者是用户,他告诉用户仅使用满足restrict要求的参数。一般,编译器无法检查您是否遵循了这一限制,如果您蔑视它也就是在让自己冒险。

【C语言关键字RESTRICT介绍】相关文章:

C语言关键字01-19

C语言关键字及其解释03-10

C语言关键字const用法03-18

C语言的32个关键字09-07

C语言的关键字和控制语句有哪些01-04

C语言初始化效率问题及关键字解释03-17

c语言的优点介绍04-13

c语言数学函数的介绍10-20

C语言的数据类型介绍03-09

C语言和C++的区别精选03-01