30
Владиславлев Виктор Системы программирования (СП) Создание СП для новых архитектур

Владиславлев Виктор

  • Upload
    leif

  • View
    63

  • Download
    0

Embed Size (px)

DESCRIPTION

Системы программирования (СП) Создание СП для новых архитектур. Владиславлев Виктор. Agenda. Содержание. Системы программирования Структура компилятора Препроцессор Компилятор Ассемблер Линковщик Динамический Линковщик Прочие системные утилиты Библиотеки Создание/Портирование СП - PowerPoint PPT Presentation

Citation preview

Page 1: Владиславлев Виктор

Владиславлев Виктор

Системы программирования (СП)Создание СП для новых архитектур

Page 2: Владиславлев Виктор

Содержание

• Системы программирования• Структура компилятора

o Препроцессорo Компиляторo Ассемблерo Линковщикo Динамический Линковщик

• Прочие системные утилиты• Библиотеки• Создание/Портирование СП

o Machine Descriptiono Двоичный интерфейс приложенияo Библиотеки

• Симулятор• Средства отладки• Средства анализа производительности• Форматы исполняемых файлов• Форматы отладочной информации

Agenda

Page 3: Владиславлев Виктор

Системы программирования

Toolchain – набор средств разработки программ• Компилятор• Бинарные утилиты• Библиотеки• Средства отладки и профилирования• И проч. (редакторы, навигаторы по коду, системы автодокументации,

верификаторы и т.д.)Примеры:• GNU toolchain – Unix/Linux/Windows на большинстве архитектур• Microsoft Visual Studio – Windows на x86• ICC – toolchain от компании Intel – Windows/Linux на x86 и IA64• Code Warrior – toochain для встроенных систем• Xcode – toochain для Mac OS X и iOS

Можно разделить• Нативные системы (host = target)• Кросс-системы (host != target)

Toolchain

Page 4: Владиславлев Виктор

ядро компилятора

Структура компилятора

Компилятор - переводит исходный код программы (написанные на языке высокого уровня) в эквивалентный код на языке целевой платформы

Compiler structure

.c.cpp.f77...

.c.cpp

.F

...

High-Level IR

High-Level IR

High-Level IR Low-Level

IR

Low-LevelIR

Low-Level IRasm

.o.obj

.out.exe

1 2 4 5 6

1. 1.Препроцессор2. 2.Front-End3. 3.Оптимизации4. 4.Кодогенератор5. 5.Ассемблер6. 6.Линкер

++ Можно проследить запуски фаз компиляции (опция ‘--verbose’ в GCC)

Page 5: Владиславлев Виктор

Препроцессирование

• Инициальная обработка1. Разбиение на строки2. Замена триграфов3. Объединение строк4. Замена комментариев

1. Рабиение на токены1. (слева направо, жадная)• Замена диграфов (в С++)

• Собственно препроцессирование• Подключение файлов (#include)• Макроподстановки (#define/undef/##)• Условная компиляция (#ifdef/if/else/elif/endif)• Управление строками (#line)• Диагностика (#error/warning)

++ Часто полезно получить препроцессированный код (опция ‘-E’ в GCC)

Preprocessing

Триграф значение??( [??) ]??< {??> }??= #??/ \??' ^??! |??- ~

/??/**/ # /**/ defi\ne FO\O 10\20#define FOO 1020

a = i+++j;

a = (i++) + j;

a = i + (++j);

Page 6: Владиславлев Виктор

Препроцессирование

• Инициальная обработка1. Разбиение на строки2. Замена триграфов3. Объединение строк4. Замена комментариев

1. Рабиение на токены1. (слева направо, жадная)• Замена диграфов (в С++)

• Собственно препроцессирование• Подключение файлов (#include)• Макроподстановки (#define/undef/##)• Условная компиляция (#ifdef/if/else/elif/endif)• Управление строками (#line)• Диагностика (#error/warning)

++ Часто полезно получить препроцессированный код (опция ‘-E’ в GCC)

Preprocessing

Триграф значение??( [??) ]??< {??> }??= #??/ \??' ^??! |??- ~

/??/**/ # /**/ defi\ne FO\O 10\20#define FOO 1020

a = i+++j;

a = (i++) + j;

a = i + (++j);

Page 7: Владиславлев Виктор

собственно Компилятор

Компилятор обрабатывает единицу трансляции (translating unit TU, compilation unit). В С/С++ это файл после препроцессирования. В FORTRAN – один файл может содержать несколько TU.Компилятор включает:1. Компилятор переднего плана (Frontend) – строит по исходному коду

промежуточное представление (Intermediate Representation – IR, или IL); включает o Лексический анализатор1. Синтаксический анализатор2. Семантический анализатор

2. Фазы Анализа и Оптимизаций представленияo их много (Основная часть курса), но можно и уменьшить: разные уровни оптимизаций

– Фазы Распределение регистров и кодогенерацияРезультат работы компилятора – язык ассемблера (ассемблер, машинный язык) целевой архитектуры

Compiler

++ Можно проследить результат работы компилятора после каждой фазы(опции ‘--dump-tree-all --dump-rtl-all’ в GCC)

Page 8: Владиславлев Виктор

трансформация Кода

int f(int b, int c){int a1 = b*5 - c;int a2 = -8*b + 2*c;return 2*a1 + a2;}

D.26 = b * 5;a1 = D.26 - c;27 = b * -4;D.28 = D.27 + c;a2 = D.28 * 2;D.20 = a1 * 2;D.29 = D.20 + a2;return D.29;

.globl f

.type f, @functionf:.LFB0:.cfi_startprocleal (%rdi,%rdi), %eaxret.cfi_endproc

Code transformation

++ Бывает полезно посмотреть ассемблерный код (опция ‘-S’ в GCC)

1. Source code2. AST3. High-level IR4. Low-level IR5. assembler

a1

-8

a2

a1 a2

ret

set (reg:SI 62)(ashift:SI (reg/v:SI 60 [ b ])(const_int 1 [0x1]);set (reg/i:SI 0 ax)(reg:SI 62);

Page 9: Владиславлев Виктор

Ассемблер

Ассемблер как программа• переводит язык ассемблера в код целевой архитектуры, сохраняемый в

исполняемом формате• Для символьных ссылок – резервирует место, подстановку реальных

адресов осуществляет линкер• КАК ПРАВИЛО, ассемблер – тривиален (парсинг, упаковщик). Исключение:

IA-64 (Itanium) (виртуальные регистры, шаблоны, скобки параллельности)Язык ассемблера• Имеет типы (наследованные от архитектуре), комментарии, объекты и пр.• характерезуется тривиальным синтаксисом• может быть не стандартизирован даже в рамках одной платформы

Assembler

mov eax, ebxIntel

movl %ebx, %eaxAT&T

Имена регистров зарезервированыСначала dst, потом src

Регистры начинаются с %b, w, l, q – размер операнда

Page 10: Владиславлев Виктор

Линковщик

Дефиниция – полное определение сущности (глобала или функции)Декларация – лишь обещание того, что где-то есть дефиниция• Объектный файл содержит дефиниции функций и глобалов• В коде есть ссылки на декларированные глобалы и/или функции• Основная задача линковщика (линкера) – реализовать чужие обещания• Проблемы: Никого не нашли – ошибка! Нескольких – (duplicate definitions):

o С++: ‘one definition rule’o С: ‘tentative definition’ для неинициализированных глобаловo FORTRAN: ‘common model’ – в каждой TU свой COMMON блок, своего размера

Инициализированный глобал Предварительное определение Декларация Дефиниция Переменная на стеке Указывает на память в куче

Linker

int G1 = 1;int G2;extern int G3;extern int f( int*);int g( int n) {int* h = malloc(n*sizeof(int));f( h);return h[ G2 ];}

bss: 000...00datacode heap

bss datacodefile

memory stack

Page 11: Владиславлев Виктор

Недостатки статических библиотек:• многократное дублирование кода в памяти• связь приложения с реализацией библиотеки навсегда

динамические библиотеки:.so в Unix, .dll в Windows, .dylib в MacOS XPIC (position-independent code) в LinuxProcedure Linkage TableGlobal Offset Tableld.so – динамический загрузчик• Мапирование кода в адресное

пространство процесса• Проблема с данными библиотеки

DLL – это не PIC, как в Linux; в Windows это называется memory mapping

Динамическая линковка Dynamic Linking

movl %edx, %esimovq %rax, %rdicall f@PLTmovq G2@GOTPCREL(%rip), %raxmovl (%rax), %eaxcltq

movl %edx, %esimovq %rax, %rdicall fmovl G2(%rip), %eaxсltq

call f…LPTf:??

a.out libname libfunction f

ld.so

LPTf:0x…f()

lib.so

Page 12: Владиславлев Виктор

Прочие бинарные утилиты

• as – ассемблер• ld – линкер• gprof – профилировшик, требует инструментирование код• ar – архиватор для создания статических библиотек (LIB – Windows)• objcopy – копирует содержимое одних объектных файлов в другие• objdump – получение информации из объектного файла, в частности,

выполняет функцию дизассемблера• readelf – показать содержимое ELF файла• strip – удаляет символы из объектного файла• gold – улучшенный линкер от Google, теперь – в стандартных утилитах• nm – получить список символов из объектного файла• c++filt – DeMangling• windmc – message compiler (Win)• windres – recourse compiler (Win)

Other binutils

_ZGVZN15UICmdWithParser11parseMemoryEPPKcmRmP7ProgramP7MachineS3_RNS_15uiParserWidth_tEE8reMemoryUICmdWithParser::parseMemory(char const**, unsigned long, unsigned long&, Program*, Machine*, unsigned long&, UICmdWithParser::uiParserWidth_t&)::reMemory

Page 13: Владиславлев Виктор

Библиотеки

Требования к стандартной библиотеке языка 1. Взаимодействие с ОС– Удобный ввод-вывод– Математические функции– Средства отладки и диагностирования программ (про assert.h)– Поддержка часто используемых типов (функции работы со строками, работа с

UNICODE)Для С это libc++ не все требования выполнены; например, п.1. – отдельный стандарт POSIXРаспространненные реализации:• GNU C Library – самая распространенная реализация, используемая в Linux• Microsoft C Run-time Library• Dietlibc – альтернативная небольшая реализация Стандартной библиотеки Си• uClibc – Стандартная библиотека Си для встраиваемых систем на базе Linux• Newlib – Стандартная библиотека языка Си для встраиваемых систем• Klibc – применяется главным образом для загрузки Linux-систем• Eglibc – разновидность glibc для встраиваемых систем• bionic – реализация стандартной библиотеки в Android

Libraries

Page 14: Владиславлев Виктор

• Для С это libstdc++o IOStreamo STL

• Библиотеки динамической поддержки языковой; для С++ это libsupc++o EH (exception handling)o RTTI (run-time type information): dynamic_cast<>, typeid , type_infoo new с синтаксисом размещения

• Библиотека поддержки компилятора; для GCC это libgcco Арифметические функции, которые не могут быть напрямую раскрыты в команды

target архитектуры (divsi3(int, int))o Функции работы с исключениями (независимые от языка) (_Unwind_GetIp)o Другие функции поддержки компилятора (_splitstack_find)

• BFD (Binary File Descriptor) library – основа большинства бинарных утилит

Библиотеки Libraries

Page 15: Владиславлев Виктор

Создание/Портирование СП

Два пути• Создание Toolchain с нуля: есть свои плюсы, но о них почти ничего не известно

(пропреитарный код, который можно продавать)• Портирование имеющегося

o Коммерческие Front-End’ы – Edison Design Groupo Открытая система программирования GCC (GNU Compiler Collection)o Еще одна: LLVM (Low-Level Virtual Machine)o UTL (Universal Translating Library)

Creating/Poring TC

Входные языки

Целевые платформы

SUNCompiler

MSCompiler

GCCLLVM

EDG Front-End

Intelcompiler

Elbruscompiler

CG1 CG2

C++C F77

Page 16: Владиславлев Виктор

• Простой пример на С и его возможное расположение в памяти• Семантические единицы: тип и размер данных, управляющие структуры,

операции, вызовы функций (что требует ABI)• Это трудоемко! Описание машины быстро решает эту задачу

Простой пример Example

Page 17: Владиславлев Виктор

• Показан процесс сборки cc1 под ARM• Сверху – блок исходных кодов, снизу – компоненты компилятора • Из MD генерируется RTL generator (expander) и кодогенератор• MD – описывает структуру генератора генератора кода

Описание Машины Machine Description (MD)

Page 18: Владиславлев Виктор

Циклограмма работы собранного компилятораSSA (static single assignment) – представления кода, при котором каждая переменная непосредственно модифицируется лишь единожды, а далее только используетсяGIMPLE – высокоуровневый язык внутреннего для GCC представления программы в SSA формеRTL (register transfer language) – низкоуровневый язык внутреннего для GCC представления программы, по сути высокоуровневый ассемблер

Цикл работы компилятора ???(MD)

Page 19: Владиславлев Виктор

Файловая структура: директория gcc/gcc/config/<target>Файлы <target>.h, .cpp и .md , который содержит:• define_insn – шаблон инструкции в генерации кода• define_split – шаблон разбиения сложных шаблонов на более простые• define_expand – именнованный шаблон, используется для генерации RTL из

GIMPLE• define_peephole – шаблон частной архитектурно-зависимой оптимизации• define_predicate – шаблон предиката (для проверки соответствия операндов

инструкции)

Структура описания в GCC GCC description structure

Page 20: Владиславлев Виктор

ABI (Application Binary Interface) – набор соглашений для обеспечения взаимодействия между приложениями, библиотеками и ОС• Размер и выравнивание данных• Формат системных вызовов• Calling Convention – cпособ передачи параметров функций и

возвращаемого значения:o Где передавать параметры: на регистрах, в стеке, через динамическую память,

комбинируя всё вышеперечисленноеo В каком порядке: прямом, обратном (проще реализовать эллипсиса)o Кто сдвигает стек обратно: callee или callero Callee/Сaller saved регистры

Какие бывают:• cdecl – через стек, справа налево, обратный сдвиг – caller • pascal – через стек, слева направо, сдвиг – callee• fastcall – на регистрах, сдвиг – callee• stdcall – через стек, справа налево, сдвиг – callee• tailcall – вызов непосредственно перед возвратом, можно не двигать стек

Двоичный интерфейс приложения ABI

callerf()calleeg()

Page 21: Владиславлев Виктор

Требования к библиотекам (в порядке убывания значимости) 1. Соответствие стандарту(корректная работа).– Код максимально написана на ЯВУ с минимальными аппаратными зависимостями– Эффективность (Premature optimazation is  the root of all evil)

В идеале необходимо создать лишь машинно-зависимую частьРассмотрим bionic. Девиз: keep it really simple!• Содержит libc, libm и немного для C++• НЕ содержит поддержки механизма исключений и wide chars• собирается общей системой сборки Android• содержит таблицу с номерами системных вызовов и их параметрами• tools/gensyscalls.py – скрипт для генерации системных вызовов• В аппаратно-зависимой части находятся setjmp()/longjmp()• Содержит динамический загрузчик ld.so

Портирование Библиотек Library Porting

Page 22: Владиславлев Виктор

Создание/портирование компилятора и ОС происходит параллельно с созданием архитектуры. Вопрос: КАК?Ответ: симуляторФункциональный симуляторЗадача – отрабатывать семантику эмулируемого кода как можно быстрееQEMU – быстрый и портируемый динамический транслятор; имеет свой IRPerformance симуляторЗадача – воссоздать потактовую модель архитектуры предельно точно• Конвейер• Кэш• Память

Очень медленныйSimPoint – обрабатывает трассы симулятора (формат BBV – Basic Block Vectors) и определяет наиболее горячие регионы исполнения для прогона на Performance симуляторе

Симулятор Simulator

Page 23: Владиславлев Виктор

Средства отладки

До отладчика• Static source analysis – анализ исходного кода до или во время компиляции

(компилятор, утилиты lint, cppcheck)• Dynamic source analysis – анализ программы на этапе исполнения;

исходный код инструментируется до/во время компиляции (Insure++)• Static binary analysis – анализ двоичных файлов до их запуска

(Антивирусы)• Dynamic binary analysis – анализ кода на этапе исполнения;

инструментируется бинарный код (valgrind, Pin)• Комбинированные решения

Отладчик• На основе аппаратной поддержки – debug registers • На основе программной поддержки: INT 1 – пошаговое исполнение; INT 3 –

однобайтовая команда (INT n – 2 байта)GBD (GNU DeBugger) – поддерживает оба механизма, для привязки к коду требуется отладочная информация, что требует поддержки компилятора. Есть gdb-server – для упрощения портирования.

Debugging tools

Page 24: Владиславлев Виктор

Valgrind

Общий механизм для запуска различных утилит анализаЗамедляет работы приложения в 10-50 разПо сути является JIT (Just-In-Time) компилятором (UCode – Собственный IR)Имеет ряд стандартных утилитАльтернатива – утилита Pin от Intel, настроена на x86, IA64, XScale>100 утилит для Pin.На горячем коде замедление 1.2-4 раза, на холодном 30-50 раз

framework

Valgrind Valgrind

X86PPC…

Build IL

IL

Code gen

init IL

Instrumented IL

Tool

Memcheck – проверка памятиCachegrind – профиль кэшаCallgrind – профиль кэша+кодаMassif – профиль кучиHelgrind – анализ многопоточностиLackey – кол-во инструкций и BBTreadSanitizer – новое от Google

Page 25: Владиславлев Виктор

• VTune – система от Intel, сбор информации о динамическом поведении приложения на основе аппаратной поддержки (множество системных регистров)

• Gprof – в основе лежит метод Монте-Карло: каждые 10мс прерывается исполнение, смотрим стек и добавляет 10мс ко времени исполнения процедуры

• Утилиты на основе valgrind (+ callgrind или cachegrind) – в основе лежит детальный подсчет инструкций, не инструментирует код, но динамически ретранслирует приложение

++ Для профилирования надо инструметрировать код (опция ‘-pg’ в GCC)

Анализ производительности Performance Analysis

Page 26: Владиславлев Виктор

index % time self children called name-----------------------------------------------0.00 0.03 53/48965 BZ2_bzWriteClose64 [29]0.00 26.95 48912/48965 BZ2_bzWrite [7][5] 73.8 0.00 26.98 48965 BZ2_bzCompress [5]1.81 25.17 48965/48965 handle_compress [6]0.00 0.00 53/56 isempty_RL [43]-----------------------------------------------1.81 25.17 48965/48965 BZ2_bzCompress [5][6] 73.8 1.81 25.17 48965 handle_compress [6]5.10 19.95 273/273 BZ2_compressBlock [8]0.12 0.00 7012881/7012881 add_pair_to_block [22]0.00 0.00 270/273 prepare_new_block [42]0.00 0.00 3/56 isempty_RL [43]0.00 0.00 3/6 init_RL [47]-----------------------------------------------11.23 5.74 273/273 BZ2_blockSort [9][10] 46.4 11.23 5.74 273 mainSort [10]5.74 0.00 316455844/316455844 mainGtU [15]-----------------------------------------------

Пример профиля Profile example

Место в профиле

Собств.время

Времяпотомков

Общее число вызовов

Откуда вызвали

Сколько вызвали отсюда

Листовая функция, вызывается из одного места в огромном цикле

Page 27: Владиславлев Виктор

Граф вызовов Call Graph

Page 28: Владиславлев Виктор

Профиль по инструкциям Instruction profiling

Page 29: Владиславлев Виктор

Исполняемые форматы

• ELF – Executable and Linkable Format (Unix, Linux)• PE – Portable Executable (Windows)• a.out – условно “непосредственный код”• COFF (XCOFF, ECOFF)

Executable Formats

Page 30: Владиславлев Виктор

• Stab• COFF• PE/COFF• OMF• IEEE-695• DWARF – рекомендован к ознакомлению

Отладочные форматы Debugging formats