Алиасинг (компьютер)

Материал из wikixw
Перейти к навигации Перейти к поиску

Термин, используемый в обработке сигналов и компьютерной графике, см. Aliasing. Метод замены имен команд в компьютерной оболочке см. в разделе Alias (command).

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

Примеры[править]

Переполнение буфера[править]

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

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

# include <stdio.h>
int  main()
{
 int  arr[2] = { 1,2  };
 int  i=10;
 /* Запись после конца arr. Undefined behavior in standard C, will write to i in some implementations. */
 arr[2] = 20;
 printf("элемент 0: %d \t", arr[0]);  // outputs 1
  printf("элемент 1: %d \t", arr[1]); // выводит 2
  printf("элемент 2: %d \t", arr[2]); // выводит 20, если произошло сглаживание
  printf("i: %d\t\t", i); // может также выводить 20, а не 10, потому чтоконечно, но компилятор мог бы сохранить меня в регистре и напечатать 10
 /* размер arr по-прежнему равен 2. */
 printf("размер arr: %d \n", sizeof(arr) / sizeof(int));

}

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

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

Указатели с псевдонимами[править]

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

Заданное aliasing[править]

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

my @array  =  (1,2,3  );
foreach  my $element (@array) {
   # Increment $element, таким образом автоматически
    # модифицируя @array, так как $element "aliased"
    # каждому из элементов @array по очереди.
   $element ++;
}
print "@array \ n";

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

Конфликты с оптимизацией[править]

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

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

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

Аппаратное aliasing[править]

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

Пример

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

A2 A1 A0 Расположение памяти
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) был закорочен на землю, таблица была бы изменена следующим образом:

A2 A1 A0 Расположение памяти
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 стали недоступными.

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

См. Также[править]

  • Сглаживание
  • Aliasing для использования слова при обработке сигналов, включая компьютерную графику

Читать[править]

/cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html

Пруф[править]

//cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html