Jump to content

Псевдонимы (вычисления)

(Перенаправлено из псевдонима указателя )

В вычислениях псевдонимы можно получить через описывают ситуацию, в которой доступ к ячейке данных в памяти разные символические имена в программе. Таким образом, изменение данных через одно имя неявно изменяет значения, связанные со всеми псевдонимами, чего программист может не ожидать. В результате псевдонимы особенно затрудняют понимание, анализ и оптимизацию программ. Анализаторы псевдонимов предназначены для получения и вычисления полезной информации для понимания псевдонимов в программах.

Переполнение буфера

[ редактировать ]

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

создается массив Если в стеке с переменной, расположенной в памяти непосредственно рядом с этим массивом , можно выполнить индексацию вне массива и напрямую изменить переменную, изменив соответствующий элемент массива. Например, если есть int массив размером 2 (для этого примера назовем его arr), рядом с другим int переменная (назовите ее i), arr[2] (т. е. третий элемент) будет иметь псевдоним i если они соседствуют в памяти.

# include <stdio.h>

int main()
{
  int arr[2] = { 1, 2 };
  int i=10;

  /* Write beyond the end of arr. Undefined behaviour in standard C, will write to i in some implementations. */
  arr[2] = 20;

  printf("element 0: %d \t", arr[0]); // outputs 1
  printf("element 1: %d \t", arr[1]); // outputs 2
  printf("element 2: %d \t", arr[2]); // outputs 20, if aliasing occurred
  printf("i: %d \t\t", i); // might also output 20, not 10, because of aliasing, but the compiler might have i stored in a register and print 10
  /* arr size is still 2. */
  printf("arr size: %lu \n", (long) (sizeof(arr) / sizeof(int)));
}

Это возможно в некоторых реализациях C, поскольку массив представляет собой блок непрерывной памяти, а ссылки на элементы массива просто смещаются от адреса начала этого блока, умноженного на размер одного элемента. Поскольку в C нет проверки границ, возможна индексация и адресация за пределами массива. Обратите внимание, что вышеупомянутое поведение псевдонимов является неопределенным поведением . Некоторые реализации могут оставлять пространство между массивами и переменными в стеке, например, для выравнивания переменных по областям памяти, кратным собственному размеру слова архитектуры . Стандарт C обычно не определяет, как данные должны располагаться в памяти. (ИСО/МЭК 9899:1999, раздел 6.2.6.1).

Компилятор не будет ошибкой пропускать эффекты псевдонимов для обращений, выходящих за пределы массива.

Псевдонимы указателей

[ редактировать ]

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

Указанный псевдоним

[ редактировать ]

В некоторых случаях может быть желательным контролируемое поведение псевдонимов (то есть заданное поведение псевдонимов, в отличие от того, которое обеспечивается расположением памяти в C). Это обычная практика в Фортране . Язык Perl программирования в некоторых конструкциях определяет поведение псевдонимов, например в foreach петли. Это позволяет напрямую изменять определенные структуры данных с меньшим количеством кода. Например,

my @array = (1, 2, 3);

foreach my $element (@array) {
    # Increment $element, thus automatically
    # modifying @array, since $element is ''aliased''
    # to each of @array's elements in turn.
    $element++;
}

print "@array \n";

в результате выведет «2 3 4». Если кто-то хочет обойти эффекты псевдонимов, можно скопировать содержимое индексной переменной в другую и изменить копию.

Конфликты с оптимизацией

[ редактировать ]

Оптимизаторам часто приходится делать консервативные предположения о переменных, когда возможно наложение псевдонимов. Например, зная значение переменной (например, x равен 5) обычно допускает определенные оптимизации (например, постоянное распространение ). Однако компилятор не может использовать эту информацию после присвоения другой переменной (например, в C, *y = 10) потому что это может быть так *y это псевдоним x. Это может произойти после такого задания, как y = &x. В результате этого поручения *y, значение x также будет изменено, поэтому распространение информации, которая x равно 5 к утверждениям, следующим *y = 10 было бы потенциально неправильно (если *y действительно это псевдоним x). Однако, если есть информация об указателях, процесс распространения констант может сделать запрос типа: can x быть псевдонимом *y? Тогда, если ответ отрицательный, x = 5 можно безопасно размножать.

Еще одна оптимизация, на которую влияет псевдонимы, — это изменение порядка кода. Если компилятор решит, что x не имеет псевдонимов *y, затем код, который использует или изменяет значение x можно переместить перед заданием *y = 10, если это улучшит планирование или позволит дополнительную оптимизацию цикла выполнить .

Чтобы обеспечить такую ​​оптимизацию предсказуемым образом, стандарт ISO для языка программирования C (включая его новую редакцию C99 , см. раздел 6.5, параграф 7) определяет, что незаконно (за некоторыми исключениями) получать доступ к одной и той же ячейке памяти с помощью указателей разные типы. Поэтому компилятор может предположить, что такие указатели не являются псевдонимами. Это правило, известное как правило строгого псевдонимов , иногда позволяет добиться впечатляющего увеличения производительности. [1] но известно, что он нарушает некоторый в остальном действительный код. Некоторые программные проекты намеренно нарушают эту часть стандарта C99. Например, Python 2.x сделал это для реализации подсчета ссылок , [2] и потребовались изменения в базовых структурах объектов в Python 3, чтобы включить эту оптимизацию. Ядро Linux делает это, потому что строгое использование псевдонимов вызывает проблемы с оптимизацией встроенного кода. [3] В таких случаях при компиляции с помощью gcc опция -fno-strict-aliasing вызывается для предотвращения нежелательных оптимизаций, которые могут привести к появлению неожиданного кода.

Аппаратное псевдонимирование

[ редактировать ]

Термин «алиасинг» также используется для описания ситуации, когда из-за выбора конструкции оборудования или сбоя оборудования один или несколько доступных битов адреса не используются в процессе выбора памяти. [4] Это может быть конструктивным решением, если доступно больше адресных битов, чем необходимо для поддержки установленных устройств памяти. В случае сбоя один или несколько адресных битов могут быть закорочены вместе или принудительно заземлены ( логический 0) или напряжение питания (логическая 1).

Пример

В этом примере предполагается, что память имеет 8 ячеек, требующих только 3 адресных строки (или бита , поскольку 2 3 = 8). Биты адреса (с именами от A2 до A0) декодируются для выбора уникальных ячеек памяти следующим образом, в стандартном режиме двоичного счетчика :

А2 А1 А0 Местоположение памяти
0 0 0 0
0 0 1 1
0 1 0 2
0 1 1 3
1 0 0 4
1 0 1 5
1 1 0 6
1 1 1 7

В таблице выше каждая из 8 уникальных комбинаций битов адреса выбирает другую ячейку памяти. Однако, если один бит адреса (скажем, A2) будет закорочен на землю, таблица будет изменена следующим образом:

А2 А1 А0 Местоположение памяти
0 0 0 0
0 0 1 1
0 1 0 2
0 1 1 3
0 0 0 0
0 0 1 1
0 1 0 2
0 1 1 3

В этом случае, когда A2 всегда равно нулю, первые четыре ячейки памяти дублируются и снова отображаются как вторые четыре. Ячейки памяти с 4 по 7 стали недоступны.

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

См. также

[ редактировать ]
  1. ^ Майк Эктон (1 июня 2006 г.). «Понимание строгого псевдонимов» .
  2. ^ Нил Шеменауэр (17 июля 2003 г.). «Строгое псевдонимы ANSI и Python» .
  3. ^ Линус Торвальдс (26 февраля 2003 г.). «Re: Неверная компиляция без -fno-strict-aliasing» .
  4. ^ Майкл Барр (27 июля 2012 г.). «Программное тестирование памяти» .
[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 9ae18f450d2c7ac809159b1a9dd82a56__1718795400
URL1:https://arc.ask3.ru/arc/aa/9a/56/9ae18f450d2c7ac809159b1a9dd82a56.html
Заголовок, (Title) документа по адресу, URL1:
Aliasing (computing) - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)