Какую выгоду для оптимизации приносит `pointer [restrict static 1]` при объявлении указателя, подобного этому? - PullRequest
0 голосов
/ 20 декабря 2018

Я читаю исходный код библиотеки (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]) {
// ...
}

Я понимаю ключевое слово restrict и static в целом, но яБоюсь, я не знаю причину этого. Я ничего не нашел в Google, возможно, я искал неправильно.

Я предполагаю, что это способ сообщить компилятору, что этот указатель указывает наодин объект. Но мне не хватает знаний по оптимизации, чтобы объяснить дальше.

Спасибо!

Ответы [ 2 ]

0 голосов
/ 20 декабря 2018

Что касается использования 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 ed через some_union_arg, который был преобразован в указатель.

0 голосов
/ 20 декабря 2018

static в этом контексте имеет следующее значение в соответствии со стандартом C:

6.7.6.3 Деклараторы функций (включая прототипы)

7 ... Если ключевое слово static также появляется в пределах [и] деривации типа массива, то для каждого вызова функции значение соответствующего фактического аргумента должно обеспечивать доступ к первому элементумассив, содержащий как минимум столько же элементов, сколько указано в выражении размера.

Это семантическое требование к программе.Если вызывающая функция не поддерживает ее, поведение не определено, и у них есть ошибка, которую они должны исправить.Поскольку указанный размер 1, это означает, что функция ожидает действительный указатель на один union some_union_type объект, и для передачи ему говорят, что NULL является неопределенным поведением само по себе.

Это способуказать в прототипе, что переданный указатель должен быть действительным.Компиляторы могут использовать эту информацию в теории и предупреждать, когда передается значение null.На практике это явно отражает требование к этому аргументу, и функция может даже решить не проверять, является ли указатель действительным перед тем, как получить к нему доступ (поскольку контракт, указанный в его прототипе , требует действительный указатель).

Квалификатор restrict в указателе означает, что функция предполагает, что указатель является единственным способом доступа к этим данным, прямо или косвенно.Так, например, если вы передадите ему адрес глобального объекта, к которому он обращается в своей реализации, поведение будет неопределенным.Это предположение способствует оптимизации компилятором в определенных местах.

...