Oracle Solaris Studio 12.2:C++ 用户指南

A.2.175.1 限定指针

为使编译器高效并行执行循环,需要确定某些左值是否指定不同的存储区域。别名是其存储区域相同的左值。由于需要分析整个程序,因此确定对象的两个指针是否为别名是一个困难而费时的过程。例如下面的函数 vsq()


示例 A–3 带两个指针的循环


extern "C"
void vsq(int n, double *a, double *b) {
    int i;
    for (i=0; i<n; i++) {
            b[i] = a[i] * a[i];
    }
}

如果编译器知道指针 ab 访问不同的对象,可以并行化循环的不同迭代的执行。如果通过指针 ab 访问的对象存在重叠,编译器以并行方式执行循环将会不安全。

在编译时,编译器并不能通过简单地分析函数 vsq() 来获悉 ab 访问的对象是否重叠;编辑器需要分析整个程序才能获取此信息。可以使用以下命令行选项指定将返回赋值指针函数参数视为限定指针:-xrestrict[=func1,...,funcn]。如果指定了函数列表,则指定函数中的指针参数被视为是限定的,否则,整个源文件中的所有指针参数都被视为是限定的(不推荐)。例如,-xrestrict=vsq 限定 vsq() 函数示例中给定的指针 ab

将指针参数声明为限定的表示指针指定不同的对象。编译器可以假定 ab 指向不同的存储区域。有了此别名信息,编译器就能够并行化循环。

正确使用 -xrestrict 至关重要。如果指针被限定为指向并非不同的对象的限定指针,编译器可能会错误地并行化循环,从而导致不确定的行为。例如,假定函数 vsq() 的指针 ab 指向的对象重叠,如 b[i]a[i+1] 是同一对象。如果 ab 未声明为限定指针,循环将以串行方式执行。如果 ab 被错误地限定为限定指针,编译器可能会并行化循环的执行,这是不安全的,因为 b[i+1] 仅应在计算 b[i] 之后进行计算。