Параметр компилятора помогает отлаживать оптимизированный код

Источник: IBM

Проблема отладки оптимизированного кода

Отладка оптимизированного кода всегда была сложной задачей, потому что программа может находиться в состоянии, недоступном для отладчиков. При оптимизации может измениться последовательность операций, добавиться или сократиться код, измениться расположение переменных, и могут произойти другие преобразования, затрудняющие сопоставление сгенерированного кода с оригинальными исходными операторами. Например, если переменная используется только при вычислении выражения, то компилятор может сгенерировать значение конечного выражения непосредственно, не указывая значение переменной в этом месте. Это усложняет процесс отладки, потому что в оптимизированной программе не будет переменной, которую программист ожидал увидеть.

Поддержка отладки в IBM XL C/C++ и XL Fortran

IBM XL C/C++ и XL Fortran предоставляют набор механизмов для поддержки отладки.

  • Параметр компилятора -g генерирует отладочную информацию для символьного отладчика. Он обеспечивает полную поддержку отладки кода без оптимизации, но плохо работает с оптимизированным кодом. Как говорилось в предыдущем разделе, состояние программы при оптимизации не сохраняется.
  • Параметр компилятора -qkeepparm ориентирован главным образом на параметры процедуры. Он гарантирует доступность для отладчика начальных значений параметров процедуры даже при оптимизации. Это оказывает незначительное влияние на производительность при выполнении программы. Затем параметр -qkeepparm предоставляет отладчику доступ к значениям входящих параметров, просто сохраняя эти значения в стеке.
  • Параметр компилятора -qoptdebug по завершении некоторых высокоуровневых преобразований создает измененный исходный код, соответствующий оптимизированному коду. Этот псевдокод лучше сопоставим с инструкциями и значениями оптимизированный программы, чем первоначальный исходный код. Когда программа, скомпилированная с этим параметром, загружается в отладчик, отлаживается псевдокод, а не исходный код.

Усовершенствования для отладки оптимизированного кода

Параметр отладки -g дополнен возможностью управления поддержкой отладки и упрощает отладку оптимизированного кода, в частности, с использованием уровня -O2. Когда включен уровень оптимизации -O2, поддерживаются все возможности отладки. Если уровень оптимизации выше, чем -O2, возможности отладки ограничены. Параметр отладки -g имеет уровни от 0 до 9.

  • -g0: отладочные данные не генерируются. Состояние программы не сохраняется (наилучшая производительность).
  • -g1: создается отладочная информация о номерах строк и именах исходных файлов. Состояние программы не сохраняется.
  • -g2: создается отладочная информация о типах, номерах строк, именах исходных файлов, а также отладочная информация о переменных ― только для отображения. При оптимизации кода состояние программы не гарантировано.
  • -g3, -g4: то же, что и для -g2, плюс то, что в начале каждой процедуры отладчику доступны значения ее параметров.
  • -g5, -g6, -g7: то же, что и для -g3 и -g4, плюс то, что отладчику доступно состояние программы в следующих избранных конструкциях языка на уровне -O2:
    • до и после циклов;
    • до и после операторов условного перехода;
    • до и после вызовов функций, а также первого исполняемого оператора функции.
  • -g8: то же, что и для -g3 и -g4, плюс то, что отладчику доступно состояние программы в начале каждого исполняемого оператора на уровне -O2.
  • -g9: то же, что и для -g8, плюс то, что пользователи могут изменять переменную в отладчике на уровне -O2. Возможность изменять переменную в отладчике также является поведением по умолчанию при отладке неоптимизированного кода (наилучшая поддержка отладки).

Поддержка отладки оптимизированного кода улучшается при значениях параметра -g5 и выше, когда становится доступным состояние программы на уровне -O2. Например, рассмотрим отладку следующего фрагмента кода с параметром -g8:

T1 = X * Y - 1;

T2 = X * Y * 3;

Q = T1 + T2;


На уровне -O2 без поддержки отладки компилятор может сгенерировать следующий код, где GRX и GRY ― регистры:

GRX = X * Y;

GRY = GRX << 2;

Q = GRY вЂ" 1;


Так как программа не вычисляет значения T1 и T2, отладчик не может отобразить правильные значения T1 и T2.

При использовании -g8 компилятор создает следующий код:

GRX = X * Y;

GRY = GRX << 2;

T1 = GRY вЂ" 1;

T2 вЂ" GRY вЂ" GRX;

Q = GRY вЂ" 1;


Программа сохраняет текущие значения T1 и T2 в памяти, так что они доступны для отладчика.

Отладка встроенной функции

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

Для улучшения поддержки отладки компилятор делает область встроенной функции явной, чтобы пользователи могли проследить тело функции по шагам. Пользователи также видят формальные параметры и локальные переменные встроенной функции. Однако пока они не могут "остановиться в функции" и заставить отладчик искать встроенные экземпляры таких функций.

Соображения производительности

Хотя расширенная поддержка отладки отрицательно влияет на производительность (потому что сохранение состояния программы исключает некоторые возможности оптимизации), компиляторы по-прежнему создают полностью отлаживаемый код, оптимизированный на уровне -O2. Согласно нашим измерениям, при использовании -g8 -O2 время выполнения можно сократить в среднем до 80% по сравнению с -O2 при увеличении времени компиляции на 14%. Конечно, время выполнения и время компиляции в значительной мере зависит от приложения.

Чтобы ограничить влияние на производительность, можно также поэкспериментировать с разными уровнями параметра -g. Например, -g5 сохраняет состояние программы только до и после вычислительных циклов, так что эта отладочная информация не мешает алгоритмам оптимизации, применяемым в теле цикла, где они особенно эффективны.

Заключение

Поддержка отладки оптимизированного кода улучшилась. Теперь пользователь может выбирать между возможностями отладки и производительностью. Пока оптимизация с полной поддержкой отладки выполняется только на уровне -O2. Мы продолжаем работу над совершенствованием поддержки отладки на более высоких уровнях оптимизации.

Демонстрации и ознакомительные версии:


Страница сайта http://185.71.96.61
Оригинал находится по адресу http://185.71.96.61/home.asp?artId=32911