Какова связь между переупорядочением команд, выполняемым компилятором, и переупорядочением команд, выполняемым процессором?
Итак, компилятор может свободно переупорядочивать фрагменты кода по соображениям производительности. Давайте предположим, что некоторый фрагмент кода, переведенный непосредственно в машинный код без оптимизации, выглядит следующим образом:
machine_instruction_1
machine_instruction_2
machine_instruction_3
machine_instruction_4
machine_instruction_5
но умный компилятор решает, что исходный порядок крайне неэффективен, и переупорядочивает тот же код, так что новый порядок получающихся машинных инструкций выглядит следующим образом:
machine_instruction_5
machine_instruction_4
machine_instruction_3
machine_instruction_2
machine_instruction_1
Все идет нормально.
Вот где начинается сложная часть. Получающиеся машинные инструкции будут выполняться процессором, который может свободно переставлять их снова любым способом, который он сочтет целесообразным из соображений производительности, при условии сохранения логики кода. Поскольку мы имеем дело с двумя "слоями" переупорядочения команд:
- первый из-за оптимизации компилятора
- второй, из-за неработоспособности процессора
Что делает переупорядочение команд во время компиляции актуальным вообще? Все, что видит процессор - это последовательность необработанных машинных инструкций без указания каких-либо предварительных оптимизаций, выполненных компилятором. Если процессор вводит свой собственный "слой" переупорядочения, почему он не делает недействительным порядок инструкций, установленный компилятором? В основном, что заставляет процессор уважать оптимизацию компилятора? Как переупорядочение во время компиляции и во время выполнения "взаимодействует", как последнее дополняет первое?
1 ответ
При рассмотрении выполнения инструкций необходимо соблюдать семантику программы. Любой порядок правильный, если это соблюдается. Конкретно, это описывается "зависимостями", которые указывают, требуют ли некоторые инструкции заданного порядка относительно правильного поведения программы. Например, рассмотрим следующую программу
1 x <= y+3
2 z <= 2*x
3 w = 5*y
4 y = 2*a
Инструкции 1 и 2 являются зависимыми. Если их относительный порядок изменяется, программа не соответствует желаемому программисту, и любое изменение порядка запрещено. По разным причинам 4 нельзя выполнить без изменений, пока y не будет использоваться 1 и 3. Существуют различные виды зависимостей, в том числе при рассмотрении потока управления.
Компилятор и оборудование пытаются переупорядочить программы, чтобы повысить их эффективность при соблюдении зависимостей. Действительно, их действия дополняют друг друга.
Компилятор может учитывать большие преобразования, чем процессор, и использует для этого более сложную эвристику. Компилятор может иметь большое представление о программе и переупорядочивать большую часть кода. Теоретически, инструкция на расстоянии, скажем, 1000, может быть смещена, если нет нарушения зависимости, и компилятор считает, что это может улучшить выполнение программы. Он может полностью реорганизовать код, развернуть циклы и т. Д. Напротив, процессор имеет относительно ограниченное окно предварительно выбранных инструкций, которые можно рассматривать для переупорядочения, и любая перестановка может касаться только близких инструкций и основана на простых методах, выполнимых в цикле.
Но процессор имеет большое преимущество. Он может выполнять динамическое изменение порядка и реагировать на случайные события. В данный момент он учитывает, какая инструкция может быть выполнена в отношении зависимостей и доступности данных, и соответственно переупорядочивает код. Это основано на динамических зависимостях, и, например, если результат предыдущей зависимой инструкции недоступен из-за отсутствия кэша, он выполнит другие инструкции, которые уважают зависимости. Последовательные запуски одной и той же программы с одними и теми же входными данными могут привести к разному упорядочению в зависимости от неправильных прогнозов веток, ошибок кэша и т. Д.
Таким образом, нет конкуренции между компилятором и процессором, но есть эффективное сотрудничество.