Как указать отсутствие псевдонимов для члена структуры? - PullRequest
0 голосов
/ 23 сентября 2018

Если вы пишете операторы вроде:

a[i] = b[i] + c[i];

... вы можете указать компилятору, что a[i], b[i] и c[i] указывают на разные места в памяти, что позволяетразличные оптимизации (например, векторизация).Это можно сделать, добавив специальное ключевое слово в их объявление:

float * __restrict__ a; // same for b and c

Однако что вы будете делать, если вместо float вы используете более сложный объект, скажем:

struct item {
    float foo, bar;
};

Рассмотрим следующий код:

float *a, *b;
item *c;
// ...
for (int i = 0; i < 42; ++i) {
    a[i] = b[i] * c[i].foo + c[i].bar;
}

В цикле компилятор заботится не о c[i], а о c[i].foo и c[i].bar.Как в этом случае может быть объявлено эквивалентное утверждение о независимости указателя в отношении отдельных полей структуры?

Ответы [ 3 ]

0 голосов
/ 24 сентября 2018

Нет необходимости делать это.

Либо компилятор достаточно умен, чтобы знать, что эти члены структуры не могут иметь псевдоним, либо он недостаточно умен, чтобы делать что-то полезное с этой информацией.

Причина, по которой у вас есть ключевые слова __restrict__ и C99 restrict, заключается в том, что в отличие от структур массивы могут иметь псевдоним.Поэтому ключевые слова предоставляют компилятору реальную и полезную информацию.

0 голосов
/ 26 сентября 2018

Стандарт не требует, чтобы компиляторы учитывали возможность использования a[anything] и b[anything] для доступа к любой части struct item.В нем перечислены типы lvalue, которые реализации всегда должны позволять использовать для доступа к структуре, такой как struct item, и среди них нет типов символов, таких как int.Никакого специального разрешения не требуется, чтобы позволить компилятору предположить, что ни a, ни b не будут иметь псевдоним struct item.

Конечно, компилятору было бы довольно бесполезно разрешать коду приниматьадрес члена структуры или объединения не символьного типа, но на самом деле никогда не разрешать использование результирующего указателя для доступа к члену, даже в случаях, когда псевдонимы не используются (*).Стандарт не делает различий между случаями, которые включают в себя псевдонимы, и случаями, которые этого не делают, и оставляет вопрос о том, когда разрешать доступ к структурам, используя значения типа l, полностью на усмотрение разработчиков.Авторы gcc и clang, возможно, решили, что самый простой способ поддержать использование указателей для структурирования элементов в сценариях сглаживания - это поддерживать их во всех сценариях, но стандарт вряд ли требует такой обработки, и я не думаю, чтоАвторы хотели, чтобы это было.

Стандарт дает возможность реализации воспользоваться преимуществом предположения, что ни a, ни b не будет иметь псевдоним c, и, тем не менее, по-прежнему поддерживать большинство программ, которые должны работать с указателями начлены структуры или профсоюза.Хотя в некоторых случаях было бы полезно использовать больше квалификаторов, подобных __restrict, я не уверен, какое дополнительное разрешение, по вашему мнению, потребуется для реализации в тех случаях, как тот, который вы показываете.

(*), т.е.ситуации, когда никакие операции не обращаются к области хранения или не получают указатель / ссылку, которая будет использоваться для этого, в моменты, когда существует более новый указатель / ссылка, который также будет использоваться для доступа или обращения к одному и тому же хранилищу конфликтующим образом.

0 голосов
/ 23 сентября 2018

На данный момент мне удалось решить проблему с помощью:

#pragma GCC ivdep

Однако это полностью отключает проверку зависимостей.Я все еще был бы заинтересован в более избирательном решении.

...