Презентацию к данной лекции Вы можете скачать здесь.
Транслятор выполняет преобразование программы, написанной на одном языке программирования в программу на другом языке программирования.
Компилятор выполняет преобразование программы, написанной на языке программирования (как правило, высокого уровня) в программу на языке машинного уровня.
Результат трансляции и компиляции должны быть эквивалентны исходным программам – прежде всего, должна сохраняться корректность алгоритма.
Лексический анализ - включает распознавание лексем языка программирования, замену их соответствующими кодами.
Лексемы - элементарные единицы, наделенные определенным "смыслом" и входящие в структуру предложения языка (ключевые или зарезервированные слова, константы, имена и т.д.).
Синтаксический анализ - проверка правильности использования предложений языка в соответствии с его грамматикой. Остальные фазы компиляции выполняются только при отсутствии синтаксических ошибок.
Трансляция кода в промежуточную форму - преобразование программы в матрицу промежуточного кода. Каждая строка матрицы содержит тройку: код операции и два операнда. Промежуточные коды не имеют прямых аналогов в системе машинных команд, поэтому данную форму представления программы называют машинно-независимой.
Оптимизация - уменьшение избыточности программы по затратам процессорного времени и памяти. Пользователь может управлять процессом оптимизации, используя подходящие сочетания ключей (опций) оптимизации.
Распределение памяти - определение объемов памяти каждого вида, используемого в программе. На этом этапе в матрицу промежуточного кода вносятся коды резервирования памяти . Каждая программа использует по крайней мере два вида памяти: статическую - для размещения данных и кодов программы, и стековую - для обращения к подпрограммам.
Генерация кода - подстановка кодовых образцов на выходном языке, соответствующих промежуточным кодам программы. Выполняется машинно-зависимая оптимизация программы – с учетом особенностей архитектуры целевой платформы.
Функции лексического анализатора:
Лексический анализатор (сканер, лексер) учитывает особенности языка программирования. Это включает форматирование исходного текста, интерпретацию пробелов и т.д.
Лексический анализатор использует:
Таблица терминальных символов - таблица, содержащая терминальные символы языка, коды лексем и другую информацию.
Таблица символических имен - таблица, содержащая имена переменных, их тип, значение и другую информацию.
Таблица литералов - таблица, содержащая литералы (константы), их тип и другую информацию. Литералу выделяется ячейка памяти, в которую записывается константа. Далее все появления этого литерала заменяются обращениями по адресу этой ячейки.
Результат работы сканера - последовательность кодов лексем. Код лексемы представляется кодом таблицы и спецификатором. Спецификатор задает номер строки в таблице, куда занесена лексема.
Синтаксис и семантика.
Синтаксис - множество правил, описывающих структуру предложений языка (порядок следования лексем). Речь идет о формальной структуре предложений, а не о смысле.
Семантика - множество правил интерпретации смысла предложения.
Синтаксический анализ - построение дерева грамматического разбора обрабатываемого текста. Текст состоит из предложений.
Результат анализа исходного предложения в терминах грамматических конструкций представляется в виде дерева. Такие деревья обычно называются деревьями грамматического разбора или синтаксическими деревьями.
Таблица терминальных символов - таблица, содержащая терминальные символы языка, коды лексем и другую информацию.
Таблица символических имен - таблица, содержащая имена переменных, их тип, значение и другую информацию.
Таблица литералов - таблица, содержащая литералы (константы), их тип и другую информацию. Литералу выделяется ячейка памяти, в которую записывается константа. Далее все появления этого литерала заменяются обращениями по адресу этой ячейки.
Результат работы сканера - последовательность кодов лексем. Код лексемы представляется кодом таблицы и спецификатором. Спецификатор задает номер строки в таблице, куда занесена лексема.
Использование возможностей автоматической оптимизации компилятора может дать значительный выигрыш в производительности
Если одно и то же подвыражение встречается несколько раз, компилятор может вычислить его один раз, а все последующие включения заменяются вычисленным значением:
a = (b+35) * (b+35); c = 12.0 * (b+35);
в результате удаления общего подвыражения превращается в следующий:
tmp = b + 35; a = tmp * tmp; c = 12.0 * tmp;
Развертка заключается в преобразовании цикла в линейную последовательность операций. Выигрыш в производительности достигается благодаря снижению накладных расходов на организацию цикла. Эффективным этот прием может быть в случае, когда тело цикла очень маленькое:
ifor (i = 0; i < 2; i++) a[i] = 2.0 * d[i];
После развертки:
a[0] = 2.0 * d[0]; a[1] = 2.0 * d[1]; a[2] = 2.0 * d[2];
Выражения, не зависящие от счетчика цикла (инварианты цикла), целесообразно выносить за пределы цикла, так как это позволяет уменьшить количество операций:
for (i = 0; i < 10; i++) {
a[i] = b * i + 0.35;
}
преобразуется следующим образом:
temp = b * 2.0 + 0.35;
for (i = 0; i < 10; i++) {
a[i] = temp;}
Это преобразование заключается в замене обращения к функции ее кодом. Выигрыш в производительности может быть получен благодаря уменьшению накладных расходов на вызов функции и возвращение из нее, а также на передачу параметров.
Часто подстановка функции увеличивает эффективность использования кэш-памяти, так как код становится непрерывным.
Недостатком является увеличение размера программы, которое тем более заметно, чем больше размер функции и чем больше число обращений к ней.
Подвыражение, содержащее только константы, вычисляется, а результат его вычисления подставляется в код программы:
a = b + 2.0 / 3.0;
Компилятор заменит данный код следующим:
a = b + 0.666666666666666666667;
Первый вариант более удобен для программиста, поскольку улучшает читаемость кода.
Упростить свертку констант компилятором можно, разместив константное выражение в скобках.
При автоматической оптимизации указатель или ссылка могут быть удалены, если известен их адресат:
void sub(int * p) {
*p = *p - 5;}
int main()
{
int a;
a = 10;
sub(a);
В результате преобразования генерируется следующий код:
a = 10;
a -= 5;
Этот вид оптимизации заключается в объединении одинаковых фрагментов кода, например фрагмент кода:
if (b) { y = x*x; z = y * 1.5; }
else {
y = sin(x); z = y * 1.5;
}
после оптимизации будет выглядеть следующим образом:
if (b) { y = x*x; }
else { y = sin(x); }
z = y * 1.5;
Алгебраическая редукция заключается в упрощении алгебраических выражений. Компиляторы могут выполнять редукцию относительно простых выражений, хотя и с определенными ограничениями.
a * b + a * c = a * (b + c) A + a + a + a = a * 4 -(-a) = a A - a = 0 (-a) * (-b) = a * b a * 1 = a a / a = 1 …
Следует обращать внимание на корректность программы после оптимизации с использованием алгебраической редукции.
Эквивалентные преобразования логических выражений, приводящие к понижению их сложности. Примеры:
!(!a) = a (ab) || (ac) = a(b||c) !a !b = !(a || b) a !a = false, a || !a = true a true = a, a || false = a a false = false, a || true = true a a = a (ab) || (!ac) = a ? b : c
Примеры ключей управления точностью:
/fp:precise (-fp-model precise)
/fp:source (-fp-model source)
/fp:fast (-fp-model fast
При выполнении арифметических операций с плавающей точкой изменение последовательности операндов может привести к изменению результата пвычисления арифметического выражения. В примере:
float a = -1.0E8, b = 1.0E8, c = 1.23456, y;
y = a + b + c;
printf("%f\n", y);
y = b + c + a;
printf("%f", y);
оба результата – разные. ...
и т.д.
Пример изменения поведения программы после оптимизации уровня /O2
bool func()
{
int a(1000), b(0);
for(int i = 0; i < 10000; i++)
b = (a-i)/(a-i)*b;
return false;
}
Intel - компиляторы C/C++, Fortran. Включены в состав различных пакетов ПО для профессионального разработчика.
Поддерживаются платформы Microsoft Windows и Linux.
Поддерживается работа с оптимизированными библиотеками: Intel®MKL, Intel®IPP.
Эффективная оптимизация для архитектур Intel.
Улучшенная поддержка векторизации (увеличенная разрядность векторных инструкций).
Поддержка Fortran 2008.
Интеграция с Microsoft Visual Studio.
Ссылка на ресурс: http://software.intel.com
GNU Compiler Collection (GCC) - компиляторы C/C++, Объектный C, Fortran, Ada, Java. Поддерживается платформа Linux. Распространяется свободно, в том числе в исходных кодах.
Поддерживаются различные варианты оптимизации, отладки, кодогенерации, компиляции для разных платформ.
Поддерживается Intel® CilkTM Plus.
Ссылка на ресурс: http://gcc.gnu.org/
Oracle Solaris Studio - компиляторы C/C++ и Fortran. Поддерживаются платформы Linux и Solaris, архитектуры x86 и SPARC.
Поддерживаются различные варианты оптимизации, отладки, кодогенерации.
Ссылка на ресурс: http://www.oracle.com
PGI Workstation - компиляторы C/C++ и Fortran. Поддерживаются платформы Linux, Microsoft Windows и MacOS, архитектуры x86, AMD и CUDA.
Поддерживаются различные варианты оптимизации, автоматического распараллеливания, отладки, интеграция с Microsoft Visual Studio.
Fortran 2003.
Ссылка на ресурс: http://www.pgroup.com/
NAG (Numerical Algorithms Group) Fortran Compiler - компилятор Fortran. Поддерживаются платформы Unix, Microsoft Windows и MacOS.
Поддерживаются различные варианты оптимизации, автоматического распараллеливания, отладки.
Fortran 2003/2008.
Ссылка на ресурс: http://www.nag.co.uk
Microsoft Visual C++ - поддерживается платформа Microsoft Windows.
Интеграция в Microsoft Visual Studio.
Ссылка на ресурс: http://www.microsoft.com
Open64
Ссылка на ресурс: http://www.open64.net
Clang
Ссылка на ресурс: http://clang.llvm.org
Portable C compiler
Ссылка на ресурс: http://pcc.ludd.ltu.se/
и другие.
Презентацию к данной лекции Вы можете скачать здесь.
Транслятор выполняет преобразование программы, написанной на одном языке программирования в программу на другом языке программирования.
Компилятор выполняет преобразование программы, написанной на языке программирования (как правило, высокого уровня) в программу на языке машинного уровня.
Результат трансляции и компиляции должны быть эквивалентны исходным программам – прежде всего, должна сохраняться корректность алгоритма.
Лексический анализ - включает распознавание лексем языка программирования, замену их соответствующими кодами.
Лексемы - элементарные единицы, наделенные определенным "смыслом" и входящие в структуру предложения языка (ключевые или зарезервированные слова, константы, имена и т.д.).
Синтаксический анализ - проверка правильности использования предложений языка в соответствии с его грамматикой. Остальные фазы компиляции выполняются только при отсутствии синтаксических ошибок.
Трансляция кода в промежуточную форму - преобразование программы в матрицу промежуточного кода. Каждая строка матрицы содержит тройку: код операции и два операнда. Промежуточные коды не имеют прямых аналогов в системе машинных команд, поэтому данную форму представления программы называют машинно-независимой.
Оптимизация - уменьшение избыточности программы по затратам процессорного времени и памяти. Пользователь может управлять процессом оптимизации, используя подходящие сочетания ключей (опций) оптимизации.
Распределение памяти - определение объемов памяти каждого вида, используемого в программе. На этом этапе в матрицу промежуточного кода вносятся коды резервирования памяти . Каждая программа использует по крайней мере два вида памяти: статическую - для размещения данных и кодов программы, и стековую - для обращения к подпрограммам.
Генерация кода - подстановка кодовых образцов на выходном языке, соответствующих промежуточным кодам программы. Выполняется машинно-зависимая оптимизация программы – с учетом особенностей архитектуры целевой платформы.
Функции лексического анализатора:
Лексический анализатор (сканер, лексер) учитывает особенности языка программирования. Это включает форматирование исходного текста, интерпретацию пробелов и т.д.
Лексический анализатор использует:
Таблица терминальных символов - таблица, содержащая терминальные символы языка, коды лексем и другую информацию.
Таблица символических имен - таблица, содержащая имена переменных, их тип, значение и другую информацию.
Таблица литералов - таблица, содержащая литералы (константы), их тип и другую информацию. Литералу выделяется ячейка памяти, в которую записывается константа. Далее все появления этого литерала заменяются обращениями по адресу этой ячейки.
Результат работы сканера - последовательность кодов лексем. Код лексемы представляется кодом таблицы и спецификатором. Спецификатор задает номер строки в таблице, куда занесена лексема.
Синтаксис и семантика.
Синтаксис - множество правил, описывающих структуру предложений языка (порядок следования лексем). Речь идет о формальной структуре предложений, а не о смысле.
Семантика - множество правил интерпретации смысла предложения.
Синтаксический анализ - построение дерева грамматического разбора обрабатываемого текста. Текст состоит из предложений.
Результат анализа исходного предложения в терминах грамматических конструкций представляется в виде дерева. Такие деревья обычно называются деревьями грамматического разбора или синтаксическими деревьями.
Таблица терминальных символов - таблица, содержащая терминальные символы языка, коды лексем и другую информацию.
Таблица символических имен - таблица, содержащая имена переменных, их тип, значение и другую информацию.
Таблица литералов - таблица, содержащая литералы (константы), их тип и другую информацию. Литералу выделяется ячейка памяти, в которую записывается константа. Далее все появления этого литерала заменяются обращениями по адресу этой ячейки.
Результат работы сканера - последовательность кодов лексем. Код лексемы представляется кодом таблицы и спецификатором. Спецификатор задает номер строки в таблице, куда занесена лексема.
Использование возможностей автоматической оптимизации компилятора может дать значительный выигрыш в производительности
Если одно и то же подвыражение встречается несколько раз, компилятор может вычислить его один раз, а все последующие включения заменяются вычисленным значением:
a = (b+35) * (b+35); c = 12.0 * (b+35);
в результате удаления общего подвыражения превращается в следующий:
tmp = b + 35; a = tmp * tmp; c = 12.0 * tmp;
Развертка заключается в преобразовании цикла в линейную последовательность операций. Выигрыш в производительности достигается благодаря снижению накладных расходов на организацию цикла. Эффективным этот прием может быть в случае, когда тело цикла очень маленькое:
ifor (i = 0; i < 2; i++) a[i] = 2.0 * d[i];
После развертки:
a[0] = 2.0 * d[0]; a[1] = 2.0 * d[1]; a[2] = 2.0 * d[2];
Выражения, не зависящие от счетчика цикла (инварианты цикла), целесообразно выносить за пределы цикла, так как это позволяет уменьшить количество операций:
for (i = 0; i < 10; i++) {
a[i] = b * i + 0.35;
}
преобразуется следующим образом:
temp = b * 2.0 + 0.35;
for (i = 0; i < 10; i++) {
a[i] = temp;}
Это преобразование заключается в замене обращения к функции ее кодом. Выигрыш в производительности может быть получен благодаря уменьшению накладных расходов на вызов функции и возвращение из нее, а также на передачу параметров.
Часто подстановка функции увеличивает эффективность использования кэш-памяти, так как код становится непрерывным.
Недостатком является увеличение размера программы, которое тем более заметно, чем больше размер функции и чем больше число обращений к ней.
Подвыражение, содержащее только константы, вычисляется, а результат его вычисления подставляется в код программы:
a = b + 2.0 / 3.0;
Компилятор заменит данный код следующим:
a = b + 0.666666666666666666667;
Первый вариант более удобен для программиста, поскольку улучшает читаемость кода.
Упростить свертку констант компилятором можно, разместив константное выражение в скобках.
При автоматической оптимизации указатель или ссылка могут быть удалены, если известен их адресат:
void sub(int * p) {
*p = *p - 5;}
int main()
{
int a;
a = 10;
sub(a);
В результате преобразования генерируется следующий код:
a = 10;
a -= 5;
Этот вид оптимизации заключается в объединении одинаковых фрагментов кода, например фрагмент кода:
if (b) { y = x*x; z = y * 1.5; }
else {
y = sin(x); z = y * 1.5;
}
после оптимизации будет выглядеть следующим образом:
if (b) { y = x*x; }
else { y = sin(x); }
z = y * 1.5;
Алгебраическая редукция заключается в упрощении алгебраических выражений. Компиляторы могут выполнять редукцию относительно простых выражений, хотя и с определенными ограничениями.
a * b + a * c = a * (b + c) A + a + a + a = a * 4 -(-a) = a A - a = 0 (-a) * (-b) = a * b a * 1 = a a / a = 1 …
Следует обращать внимание на корректность программы после оптимизации с использованием алгебраической редукции.
Эквивалентные преобразования логических выражений, приводящие к понижению их сложности. Примеры:
!(!a) = a (ab) || (ac) = a(b||c) !a !b = !(a || b) a !a = false, a || !a = true a true = a, a || false = a a false = false, a || true = true a a = a (ab) || (!ac) = a ? b : c
Примеры ключей управления точностью:
/fp:precise (-fp-model precise)
/fp:source (-fp-model source)
/fp:fast (-fp-model fast
При выполнении арифметических операций с плавающей точкой изменение последовательности операндов может привести к изменению результата пвычисления арифметического выражения. В примере:
float a = -1.0E8, b = 1.0E8, c = 1.23456, y;
y = a + b + c;
printf("%f\n", y);
y = b + c + a;
printf("%f", y);
оба результата – разные. ...
и т.д.
Пример изменения поведения программы после оптимизации уровня /O2
bool func()
{
int a(1000), b(0);
for(int i = 0; i < 10000; i++)
b = (a-i)/(a-i)*b;
return false;
}
Intel - компиляторы C/C++, Fortran. Включены в состав различных пакетов ПО для профессионального разработчика.
Поддерживаются платформы Microsoft Windows и Linux.
Поддерживается работа с оптимизированными библиотеками: Intel®MKL, Intel®IPP.
Эффективная оптимизация для архитектур Intel.
Улучшенная поддержка векторизации (увеличенная разрядность векторных инструкций).
Поддержка Fortran 2008.
Интеграция с Microsoft Visual Studio.
Ссылка на ресурс: http://software.intel.com
GNU Compiler Collection (GCC) - компиляторы C/C++, Объектный C, Fortran, Ada, Java. Поддерживается платформа Linux. Распространяется свободно, в том числе в исходных кодах.
Поддерживаются различные варианты оптимизации, отладки, кодогенерации, компиляции для разных платформ.
Поддерживается Intel® CilkTM Plus.
Ссылка на ресурс: http://gcc.gnu.org/
Oracle Solaris Studio - компиляторы C/C++ и Fortran. Поддерживаются платформы Linux и Solaris, архитектуры x86 и SPARC.
Поддерживаются различные варианты оптимизации, отладки, кодогенерации.
Ссылка на ресурс: http://www.oracle.com
PGI Workstation - компиляторы C/C++ и Fortran. Поддерживаются платформы Linux, Microsoft Windows и MacOS, архитектуры x86, AMD и CUDA.
Поддерживаются различные варианты оптимизации, автоматического распараллеливания, отладки, интеграция с Microsoft Visual Studio.
Fortran 2003.
Ссылка на ресурс: http://www.pgroup.com/
NAG (Numerical Algorithms Group) Fortran Compiler - компилятор Fortran. Поддерживаются платформы Unix, Microsoft Windows и MacOS.
Поддерживаются различные варианты оптимизации, автоматического распараллеливания, отладки.
Fortran 2003/2008.
Ссылка на ресурс: http://www.nag.co.uk
Microsoft Visual C++ - поддерживается платформа Microsoft Windows.
Интеграция в Microsoft Visual Studio.
Ссылка на ресурс: http://www.microsoft.com
Open64
Ссылка на ресурс: http://www.open64.net
Clang
Ссылка на ресурс: http://clang.llvm.org
Portable C compiler
Ссылка на ресурс: http://pcc.ludd.ltu.se/
и другие.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.