При каких обстоятельствах компилятор может изменить порядок выполнения программных инструкций?

StackOverflow https://stackoverflow.com/questions/866840

  •  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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top