当声明这样的指针时,`pointer [restrict static 1]`带来什么优化好处?

时间:2018-12-20 05:52:15

标签: c compiler-optimization

我正在阅读库(QNNPack)的源代码,并注意到这一行(https://github.com/pytorch/QNNPACK/blob/24d57f21503ba8ab0f8bb5d24148754a91266b9c/src/q8gemm/6x4-neon.c#L23):

void funcName(..., 
    const union some_union_type some_union_arg[restrict static 1]) {
// ...
}

我通常会理解关键字restrictstatic,但是恐怕我不知道其背后的原因。我在Google上找不到任何东西,也许我搜索错误。

我猜这里是一种告诉编译器此指针指向单个对象的方法。但是我缺乏优化知识,无法进一步解释。

谢谢!

2 个答案:

答案 0 :(得分:2)

在这种情况下,

static根据C标准具有以下含义:

  

6.7.6.3函数声明符(包括原型)

     

7 ...如果关键字static也出现在   数组类型派生,然后对于每次调用该函数,   相应实际参数的值应提供对   数组的第一个元素,其大小至少与size表达式指定的元素相同。

这是程序的语义要求。如果函数的调用者不支持该函数,则该行为是未定义的,并且必须修复一个错误。由于指定的大小为1,因此这意味着该函数希望有一个指向单个union some_union_type对象的有效指针,并传递NULL本身是未定义的行为。

这是一种在原型中指定所传递的指针必须有效的方法。编译器可以在理论上利用此信息并在传递null时发出警告。在实践中,此文档显式地记录了对该参数的要求,并且该函数甚至可以选择在访问该指针之前不检查该指针是否有效(因为它在其原型所指定的协定要求有效的指针)。< / p>

指针上的restrict限定符意味着函数假定指针是直接或间接访问此数据的唯一方法。因此,例如,如果要向其传递在其实现中访问的全局对象的地址,则该行为将是不确定的。这种假设有助于编译器在某些地方进行优化。

答案 1 :(得分:1)

关于您示例中static的用法,我们有this

  

将参数声明为“类型数组”调整为“类型的合格指针”,其中类型限定符(如果有)是在数组类型派生的[和]中指定的那些。如果关键字static也出现在数组类型派生的[和]中,则对于函数的每次调用,相应的实际参数的值均应提供对数组第一个元素的访问,且至少为大小表达式指定的许多元素。

关于您示例中restrict的用法,我们有this

  

在函数声明中,关键字restrict可能出现在用于声明函数参数数组类型的方括号内 。它限定将数组类型转换为的指针类型

void f(int m, int n, float a[restrict m][n], float b[restrict m][n]);
void g12(int n, float (*p)[n]) {
   f(10, n, p, p+10); // OK
   f(20, n, p, p+10); // possibly undefined behavior (depending on what f does)
}

结合以上示例:

void funcName(..., 
    const union some_union_type some_union_arg[restrict static 1]) {
// ...
}

表示,每当调用funcName时,传递的参数(some_union_arg)将具有至少1个元素,该函数将可以访问该元素,并且通过restrict进行此访问{1}}已被转换为指针。