14

有没有办法告诉 C99 编译器我要访问给定数组的唯一方法是使用 myarray[index] ?说这样的话:

int heavy_calcualtions(float* restrict range1, float* restrict range2)
{
    float __I promise I won't alias this__ tmpvalues[1000] = {0};

    ....
    heavy calculations using range1, range2 and tmpvalues;
    ....
}

通过使用限制,我承诺我不会为 range1 和 range2 设置别名,但是我如何为函数内声明的数组做同样的事情?

4

2 回答 2

12

尽管 Jeff 的回答是正确的,即您始终可以创建指向已分配数组的指针,但事实是编译器在编译时知道tmpvalues 不会被别名,因为变量被声明为实际数组,而不是指针. 给数组取别名的唯一机会是声明一个指向它的指针,所以如果你不这样做,就没有必要将它声明为restrict. 如果tmpvalues是函数中唯一的变量,这一点会更加明显。

如果您将指针传递给另一个函数,则可能会出现问题,那么您应该在此处说明接收到的指针是否受到限制。

我遇到的与此主题相关的文档包括C99

令 D 是一个普通标识符的声明,它提供了一种将对象 P 指定为指向类型 T 的限制限定指针的方法。

请注意,它仅适用于指针。

TI 的这份其他文档使用restrict关键字提供了一些性能调整提示。除了所有提示之外,第 3.3 节还提供了可以应用此类型限定符以及何时不可以应用的示例。查找x第 16 页中间的数组声明,它声明它没有声明指针,因此不能被restrict- 限定。

于 2016-08-25T07:30:17.483 回答
4

为什么不能执行以下操作?您没有tmpvalues通过该变量访问与关联的数据,因此在代码的计算密集型部分使用限制指针是有效的。

#include <stdio.h>
#include <stdlib.h>

int heavy_calcs(int n, float* restrict range1, float* restrict range2)
{
    if (n>1000) return 1;
    float tmpvalues[1000] = {0};
    {
        float * restrict ptv = tmpvalues;
        for (int i=0; i<n; i++) {
            ptv[i] = range1[i] + range2[i];
        }
    }
    return 0;
}

int main(int argc, char * argv[])
{
    int n = (argc>1) ? atoi(argv[1]) : 1000;
    float * r1 = (float*)malloc(n*sizeof(float));
    float * r2 = (float*)malloc(n*sizeof(float));
    int rc = heavy_calcs(n,r1,r2);
    free(r1);
    free(r2);
    return rc;
}

我通过 Intel 15 编译器运行它,它对循环进行矢量化没有问题。当然,与我假设的循环相比,这个循环是微不足道的,所以你的里程可能会有所不同。

于 2015-04-28T21:07:20.053 回答