Смещение указателя - Pointer aliasing
Было предложено, чтобы эта статья была слился в Сглаживание (вычисления). (Обсуждать) Предлагается с мая 2020 года. |
В компьютерное программирование, сглаживание относится к ситуации, когда к одной и той же ячейке памяти можно получить доступ, используя разные имена.
Например, если функция принимает два указателя А
и B
которые имеют одинаковое значение, то имя А [0]
псевдонимы имени B [0]
. В этом случае мы говорим указатели А
и B
псевдоним друг друга. Обратите внимание, что концепция псевдонима указателя не очень четко определена - два указателя А
и B
могут или не могут совпадать друг с другом, в зависимости от того, какие операции выполняются в функции с использованием А
и B
.
Псевдоним и переупорядочивание
Псевдонимы вводят строгие ограничения на порядок выполнения программы. Если два доступа на запись, псевдонимы которых встречаются последовательно в тексте программы, они должны происходить последовательно в конечном машинном коде. Изменение порядка доступа приведет к неверному результату программы (в общем случае). То же самое верно для доступа для записи и для чтения.
Однако, если два доступа для чтения, псевдонимы которых происходят последовательно в тексте программы, они не обязательно должны происходить в одной и той же последовательности в машинном коде - доступ для чтения с псевдонимом можно безопасно изменить. Это связано с тем, что базовые данные не изменяются операцией чтения, поэтому всегда считывается одно и то же значение.
Жизненно важно, чтобы компилятор мог определить, какие обращения могут быть псевдонимами друг друга, чтобы оптимизация переупорядочения могла быть выполнена правильно.
Возможны несколько стратегий:
В C или же C ++, согласно строгому правилу псевдонимов, аргументы указателя в функции не считаются псевдонимами, если они указывают на принципиально разные типы, за исключением символ *
и пустота*
, который может быть псевдонимом любого другого типа. Некоторые компиляторы позволяют отключать правило строгого псевдонима, так что любой аргумент указателя может быть псевдонимом любых других аргументов указателя. В этом случае компилятор должен предположить, что любой доступ через эти указатели может быть псевдонимом. Это может помешать некоторым оптимизациям.
В C99, то ограничивать
было добавлено ключевое слово, которое указывает, что аргумент указателя не является псевдонимом любого другого аргумента указателя.
В Фортран аргументы процедуры и другие переменные не могут быть псевдонимами друг друга (если они не являются указателями или не имеют целевого атрибута), и компилятор предполагает, что это не так. Это обеспечивает отличную оптимизацию и является одной из основных причин репутации Fortran как быстрого языка. (Обратите внимание, что псевдонимы все еще могут возникать в функции Fortran. Например, если А
это массив и я
и j
индексы, которые имеют одинаковое значение, тогда A [i]
и A [j]
- это два разных имени для одной и той же области памяти. К счастью, поскольку у базового массива должно быть то же имя, можно провести анализ индекса, чтобы определить случаи, когда A [i]
и A [j]
не может псевдоним.)
В чистый функционал языков, аргументы функций обычно могут быть псевдонимами друг друга, но все указатели доступны только для чтения. Таким образом, нет анализ псевдонимов нужно сделать.[нужна цитата ]
Псевдонимы и многопоточность
Если несколько потоков имеют имена, являющиеся псевдонимами одной и той же области памяти, возникают две проблемы.
Во-первых, если область памяти не защищена каким-либо образом, то операции чтения-изменения-записи, которые не являются атомарными, могут чередоваться с аналогичными операциями в другом потоке, давая неверные результаты. В этом случае необходимо использовать какую-либо форму примитива синхронизации (например, критическая секция ).
Во-вторых, даже при синхронизации, если два доступа с псевдонимом происходят в разных потоках неупорядоченным образом, поведение программы может стать недетерминированным - разные запуски одной и той же программы на одних и тех же данных могут давать разные результаты. Таким образом, часто бывает важно установить явный порядок между потоками, имеющими псевдонимы.