Зависимость от данных - Data dependency
А зависимость данных в Информатика это ситуация, в которой оператор программы (инструкция) относится к данным предыдущего оператора. В теория компилятора метод, используемый для обнаружения зависимостей данных между операторами (или инструкциями), называется анализ зависимости.
Есть три типа зависимостей: данные, имя и контроль.
Зависимости данных
Предполагая заявление и , зависит от если:
куда:
- набор ячеек памяти, читаемых и
- это набор ячеек памяти, записанных
- и существует возможный путь выполнения во время выполнения от к
Это Условие называется Условием Бернштейна, названным А. Дж. Бернштейном.
Существуют три случая:
- Анти-зависимость: , и читает что-то перед перезаписывает это
- Зависимость от потока (данных): , и пишет перед тем, как что-то прочитает
- Выходная зависимость: , и оба записывают одну и ту же ячейку памяти.
Зависимость потока (Истинная зависимость)
Зависимость потока, также известная как зависимость данных или истинная зависимость, или чтение после записи (RAW), возникает, когда инструкция зависит от результата предыдущей инструкции:
1. А = 32. В = А3. C = B
Инструкция 3 действительно зависит от инструкции 2, так как окончательное значение C зависит от обновления инструкции B. Инструкция 2 действительно зависит от инструкции 1, так как окончательное значение B зависит от инструкции обновления A. Поскольку инструкция 3 действительно зависит если инструкция 2 и инструкция 2 действительно зависят от инструкции 1, инструкция 3 также действительно зависит от инструкции 1. Параллелизм на уровне инструкций поэтому не вариант в этом примере.[1]
Анти-зависимость
Анти-зависимость, также известная как запись после чтения (WAR), возникает, когда инструкция требует значения, которое позже обновляется. В следующем примере инструкция 2 не зависит от инструкции 3 - порядок этих инструкций не может быть изменен, и они не могут выполняться параллельно (возможно, изменение порядка инструкций), так как это повлияет на окончательное значение A.
1. B = 32. A = B + 13. B = 7
Анти-зависимость - это пример зависимость от имени. То есть переименование переменных могло бы удалить зависимость, как в следующем примере:
1. В = 3Н. В2 = В2. А = В2 + 13. В = 7
Новая переменная B2 была объявлена как копия B в новой инструкции N. Анти-зависимость между 2 и 3 удалена, что означает, что теперь эти инструкции могут выполняться параллельно. Однако модификация привела к новой зависимости: теперь инструкция 2 действительно зависит от инструкции N, которая действительно зависит от инструкции 1. Как зависимости потока, эти новые зависимости невозможно безопасно удалить.[1]
Выходная зависимость
Выходная зависимость, также известная как запись после записи (WAW), возникает, когда порядок инструкций влияет на окончательное выходное значение переменной. В приведенном ниже примере существует выходная зависимость между инструкциями 3 и 1 - изменение порядка инструкций в этом примере приведет к изменению конечного значения A, поэтому эти инструкции не могут выполняться параллельно.
1. B = 32. A = B + 13. B = 7
Как и в случае с анти-зависимостями, выходные зависимости зависимости имен. То есть их можно удалить путем переименования переменных, как в приведенной ниже модификации приведенного выше примера:
1. B2 = 32. A = B2 + 13. B = 7
Обычно используется следующее соглашение об именах для зависимостей данных: чтение после записи или RAW (зависимость потока), запись после чтения или WAR (анти-зависимость) или запись после записи или WAW (зависимость вывода).[1]
Зависимость управления
Инструкция B имеет управляющую зависимость от предыдущей инструкции A, если результат A определяет, следует ли выполнять B или нет. В следующем примере инструкция имеет управляющую зависимость от инструкции . Тем не мение, не зависит от потому что всегда выполняется независимо от результата .
S1. если (a == b) S2. а = а + bS3. б = а + б
Интуитивно понятно, что между двумя операторами A и B существует управляющая зависимость, если
- B может быть выполнен после A
- Результат выполнения A будет определять, будет ли выполнено B или нет.
Типичным примером является наличие управляющих зависимостей между условной частью оператора if и операторами в его истинных / ложных телах.
Формальное определение зависимости управления можно представить следующим образом:
Заявление называется контролем, зависящим от другого утверждения если только
- существует путь из к так что каждое заявление ≠ в за ним последует в каждом возможном пути до конца программы и
- не обязательно будет сопровождаться , т.е. есть путь выполнения из до конца программы, которая не проходит .
Выраженные с помощью (пост) доминирования, эти два условия эквивалентны
- пост-доминирует над всеми
- не доминирует
Построение управляющих зависимостей
Управляющие зависимости по сути граница господства в обратном графике график потока управления (CFG).[2] Таким образом, одним из способов их построения было бы построить границу пост-доминирования CFG, а затем обратить ее, чтобы получить график зависимостей управления.
Ниже приводится псевдокод для построения границы пост-доминирования:
для каждого X в восходящем обходе дерева доминаторов выполните: PostDominanceFrontier (X) ← ∅ для каждого Y ∈ Predecessors (X) do: if momentPostDominator (Y) ≠ X: то PostDominanceFrontier (X) ← PostDominanceFrontier (X) ∪ {Y} сделано для каждого Z ∈ Children (X) do: для каждого Y ∈ PostDominanceFrontier (Z) do: if momentPostDominator (Y) ≠ X: то PostDominanceFrontier (X) ← PostDominanceFrontier (X) ∪ {Y} сделано сделано
Здесь Children (X) - это набор узлов в CFG, над которыми пост-доминирует X, а Predecessors (X) - это набор узлов в CFG, которые непосредственно предшествуют X в CFG.
После того, как карта границ пост-доминирования вычислена, ее реверсирование приведет к отображению узлов в CFG на узлы, которые зависят от них.
Подразумеваемое
Обычные программы пишутся с учетом модель последовательного выполнения. Согласно этой модели, инструкции выполняются одна за другой, атомарно (то есть в любой данный момент времени выполняется только одна инструкция) и в порядке, заданном программой.
Однако зависимости между операторами или инструкциями могут препятствовать параллелизму - параллельному выполнению нескольких инструкций либо распараллеливающим компилятором, либо процессором, использующим параллелизм на уровне инструкций. Неосторожное выполнение нескольких инструкций без учета связанных зависимостей может вызвать опасность получения неверных результатов, а именно: опасности.
Рекомендации
- ^ а б c Джон Л. Хеннесси; Дэвид А. Паттерсон (2003). Компьютерная архитектура: количественный подход (3-е изд.). Морган Кауфманн. ISBN 1-55860-724-2.CS1 maint: несколько имен: список авторов (связь)
- ^ Cytron, R .; Ferrante, J .; Rosen, B.K .; Wegman, M. N .; Задек, Ф. К. (1989-01-01). «Эффективный метод вычисления статической единой формы назначения». Материалы 16-го симпозиума ACM SIGPLAN-SIGACT по принципам языков программирования. ПОПЛ '89. Нью-Йорк, Нью-Йорк, США: ACM: 25–35. Дои:10.1145/75277.75280. ISBN 0897912942.