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

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

Upload: leif

Post on 15-Jan-2016

63 views

Category:

Documents


0 download

DESCRIPTION

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

TRANSCRIPT

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