Мощь и беспомощность автоматической оптимизации

Что не надо оптимизировать


Начнем с того, что _не_ _надо_ оптимизировать, позволяя транслятору сделать это за нас (нехай делает). В частности, практически все оптимизирующие компиляторы умеют вычислять константы на стадии трансляции. В различных русскоязычных источниках этот прием оптимизации называется как "сверткой", так и "размножением" констант, что соответствует английским терминам "constant folding/propagation". Еще один английский термин из той же кучи: "constant elimination" (буквально— "изгнание констант"). Все это синонимы и описывают один и тот же механизм вычисления константных выражения (как целочисленных, так и вещественных), в результате чего a = 2 * 2

превращается в a = 4, а x = 4*y/2 в x = 2*y.

Побочным эффектом оптимизации становится потеря переполнения (если таковое имело место быть). С точки зрения математика выражения foo = bar/4*4 и foo = bar

полностью эквиваленты, но если переменные foo и bar

целые, то не оптимизированный вариант обнуляет два младших бита bar! Некоторые программисты умышленно используют этот примем, вместо того, чтобы воспользоваться "foo = bar & (~3)", а ругаются на "глючный" оптимизатор!

За исключением Intel C++ все рассматриваемые компиляторы поддерживают "улучшенную свертку констант" ("advanced constant folding/propagation"), заменяя все константные переменные их непосредственным значением, в результате чего выражение: a = 2; b = 2 * a; c = b ? a;

превращается в c = 2, а переменные a

и b

(если они нигде более не используются) уничтожаются.



Содержание раздела