При каких обстоятельствах компилятор может изменить порядок выполнения программных инструкций?
-
22-08-2019 - |
Вопрос
Если это не настоящий вопрос тогда смело закрывайте ;)
Решение
Компилятор может изменять порядок выполнения инструкций, когда он считает нужным в целях оптимизации, и когда такие изменения не повлияют на наблюдаемое поведение кода.
Очень простой пример -
int func (int value)
{
int result = value*2;
if (value > 10)
{
return result;
}
else
{
return 0;
}
}
Наивный компилятор может сгенерировать код для этого в точности в показанной последовательности.Сначала вычислите "результат" и верните его только в том случае, если исходное значение больше 10 (если это не так, "результат" будет проигнорирован - вычисляться без необходимости).
Здравомыслящий компилятор, однако, увидел бы, что вычисление "результата" необходимо только тогда, когда "значение" больше 10, поэтому может легко переместить вычисление "значение * 2" внутрь первых фигурных скобок и сделать это, только если "значение" на самом деле больше 10 (излишне упоминать, что компилятор не действительно посмотрите на код C при оптимизации - он работает на более низких уровнях).
Это всего лишь простой пример.Можно создать гораздо более сложные примеры.Очень возможно, что функция C в конечном итоге будет выглядеть почти совсем не так, как ее представление на C в скомпилированном виде, с достаточно агрессивной оптимизацией.
Другие советы
Не только компилятор может изменить порядок выполнения (в основном для оптимизации), это делают и большинство современных процессоров.Узнайте больше о переупорядочивании выполнения и барьеры памяти.
Многие компиляторы используют нечто, называемое "устранение общего подвыражения".Например, если у вас был следующий код:
for(int i=0; i<100; i++) {
x += y * i * 15;
}
компилятор заметил бы , что y * 15 равно инвариантный (его значение не меняется).Таким образом, он вычислил бы y * 15, поместил результат в регистр и изменил оператор цикла на "x + = r0 * i".Это своего рода надуманный пример, но вы часто видите подобные выражения при работе с индексами массива или в любой другой ситуации типа base + offset.