Межпроцедурная оптимизация

Межпроцедурная оптимизация

Межпроцедурная оптимизация (англ. Interprocedural Optimization, IPO) или полнопрограммная оптимизация — оптимизация компилятора, которая затрагивает несколько процедур, зачастую находящихся в разных модулях. Такую оптимизацию можно применить, лишь проанализировав всю программу целиком.

С ростом объёма программ разработчики стали делать свой код всё более удобочитаемым и повторно используемым. Зачастую это приводит к тому, что процедуры становятся предельно общими, в то время как в конкретной программе можно обойтись и частным случаем. Задача межпроцедурной оптимизации — именно генерация таких частных случаев.

Интерпроцедурная оптимизация выполняется компилятором автоматически (иногда с указанием специальных директив). Ее активация может приводить к существенному увеличению времени компиляции. К компиляторам, умеющим выполнять указанную оптимизацию, относится Intel C++ Compiler. Компилятор Delphi не умеет выполнять подобную оптимизацию.

Содержание

Примеры

Замена параметра функции константой

Пройдя по коду, компилятор убеждается, что один из параметров всегда константа, и уничтожает его.

Было

void DoSomething(Object* aObj, int aParam)
{
  if (aObj==NULL)
    throw logic_error("aObj==NULL");
  cout << "DoSomething(" << aObj->name() << "," << aParam << ")" << endl;
}
 
int main()
{
  Object obj1, obj2;
 
  DoSomething(&obj1, 1);
  DoSomething(&obj2, 1);
 
  return 0;
}

Стало

void DoSomething(Object* aObj)
{
  if (aObj==NULL)
    throw logic_error("aObj==NULL");
  cout << "DoSomething(" << aObj->name() << "," << 1 << ")" << endl;
}
 
int main()
{
  Object obj1, obj2;
 
  DoSomething(&obj1);
  DoSomething(&obj2);
 
  return 0;
}

Замена виртуального вызова статическим

Здесь компилятор убеждается, что все реально выполняющиеся виртуальные вызовы ведут к вызову одной и той же функции. Вместо того, чтобы обращаться к таблице виртуальных методов, компилятор делает прямой вызов функции.

В том же примере, если Object::name() — виртуальный метод, оптимизированная функция будет выглядеть так.

void DoSomething(Object* aObj)
{
  if (aObj==NULL)
    throw logic_error("aObj==NULL");
  cout << "DoSomething(" << Object::name(aObj) << "," << 1 << ")" << endl;
}

Удаление незадействованного кода

После удаления получится:

void DoSomething(Object* aObj)
{
  cout << "DoSomething(" << Object::name(aObj) << "," << 1 << ")" << endl;
}

Заодно может происходить чистка таблиц виртуальных методов.

Инлайнинг

Если функция используется однократно, она напрямую включается в то место, из которого она вызывается.

Небольшие функции также можно напрямую включать в вызывающий код.

Многие языки программирования (Паскаль, Java, D) не имеют ключевого слова inline, и решение инлайнировать функцию принимается оптимизатором (в случае Java — обфускатором).



Wikimedia Foundation. 2010.

Игры ⚽ Нужно решить контрольную?

Полезное


Смотреть что такое "Межпроцедурная оптимизация" в других словарях:

  • Intel C++ compiler — Тип Компилятор Разработчик Intel Операционная система Linux, Microsoft Windows и Mac OS X Аппаратная платформа x86, x86 64, IA 64 Последняя версия …   Википедия


Поделиться ссылкой на выделенное

Прямая ссылка:
Нажмите правой клавишей мыши и выберите «Копировать ссылку»