restric关键字

来源:互联网 发布:尹欣新东方 知乎 编辑:程序博客网 时间:2024/06/05 13:44

转自:http://www.360doc.com/content/12/0416/10/1317564_204045854.shtml

补充一个APUE中的内容,即是restrict修饰符。下面一段引自Sun公司的技术文档:

  • restrict

    Objects referenced througha restrict-qualified pointer have aspecial association with that pointer. All references to thatobject must directly or indirectly use the value of this pointer.In the absence of this qualifier, other pointers can alias thisobject. Cacheing the value in an object designated througha restrict-qualified pointer is safe atthe beginning of the block in which the pointer is declared,because no pre-existing aliases may also be used to reference thatobject. The cached value must be restored to the object by the endof the block, where pre-existing aliases again become available.New aliases may be formed within the block, but these must alldepend on the value ofthe restrict-qualified pointer, so thatthey can be identified and adjusted to refer to the cached value.For a restrict-qualified pointer at filescope, the block is the body of each function in the file.

翻译过来的意思就是,通过restrict限定的指针访问的对象与指针有一个特别的联系。所有对于那个对象的访问都必须要直接或者间接的用到这个指针的值。倘若不存在restrict限定符,则其他指针可以作为这个对象的别名。如果有restrict修饰指针,则对于对象的值的缓冲在指针声明的代码块内是安全的,因为没有别名用于引用这个对象。被缓冲的值在代码块结末的不分必须被回复,因为别名可能重新起效。块内可以声明其他的别名,但是这些必须基于restrict修饰的指针的值,所以它们可以被调整为使用缓冲区内的值。对于文件域的restrict修饰符,restrict的作用域是文件的每个函数体内部。

也就是说,比如我有一个内存中的对象,如果用restrict指针修饰,则使用的时候可以把它提到CPU的cache里面进 行处理(不懂硬件,大致意思应该是这样的吧),而不必担心其他指针引用了这个对象,而让它们没有取出正确的值来。最后cache内容还是要写回内存的。

restrict修饰符于1999年通过C标准


这里的restrict让我觉得有些疑惑,一查原来是C99中增加的关键字

那么restrict的意义是什么呢?

One of the new features in the recently approved C standard C99, isthe restrict pointerqualifier. This qualifier can be applied to a data pointer toindicate that, during the scope of that pointer declaration, alldata accessed through it will be accessed only through that pointerbut not through any other pointer. The 'restrict' keyword thusenables the compiler to perform certain optimizations based on thepremise that a given object cannot be changed through anotherpointer. Now you're probably asking yourself, "doesn't constalready guarantee that?" No, it doesn't. The qualifier constensures that a variable cannot be changed througha particularpointer. However, it's stillpossible to change the variable through a different pointer.

概括的说,关键字restrict只用于限定指针;该关键字用于告知编译器,所有修改该指针所指向内容的操作全部都是基于(baseon)该指针的,即不存在其它进行修改操作的途径;这样的后果是帮助编译器进行更好的代码优化,生成更有效率的汇编代码。

举个简单的例子


int foo(int* x, int* y)
{
*= 0;
*= 1;
return *x;
}

很显然函数foo()的返回值是0,除非参数x和y的值相同。可以想象,99%的情况下该函数都会返回0而不是1。然而编译起必须保证生成100%正确的代码,因此,编译器不能将原有代码替换成下面的更优版本

int (int* x, int* y)
{
*= 0;
*= 1;
return 0;
}

 

啊哈,现在我们有了restrict这个关键字,就可以利用它来帮助编译器安全的进行代码优化了
int (int *restrict x, int *restrict y)
{
*= 0;
*= 1;
return *x;
}
此时,由于指针 x 是修改 *x的唯一途径,编译起可以确认 “*y=1; ”这行代码不会修改*x的内容,因此可以安全的优化为

int (int *restrict x, int *restrict y)
{
*= 0;
*= 1;
return 0;
}



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

例子

  考虑下面的例子:   
int ar[10];   
int * restrict restar=(int *)malloc(10*sizeof(int));   
int *par=ar;   
这里说明restar是访问由malloc()分配的内存的唯一且初始的方式。par就不是了。   那么:   
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并不是访问数组ar的唯一方式,因此并不能进行下面的优化:   par[n]+=8;  因为在par[n]+=3前,ar[n]*=2进行了改变。使用了关键字restric,编译器就可以放心地进行优化了。  这个关键字据说来源于古老的FORTRAN。有兴趣的看看这个。
0 0
原创粉丝点击