Компьютерные системы: перспектива программиста (глобальное издание)
Полное погружение в то, как компьютерные системы выполняют программы и хранят информацию. Этот курс закрывает разрыв между высоким уровнем программирования и базовым аппаратным обеспечением, охватывая представление на машинном уровне, архитектуру процессора, иерархию памяти и параллельное программирование.
Обзор курса
📚 Краткое содержание
Полное углубление в то, как компьютерные системы выполняют программы и хранят информацию. Этот курс мостит разрыв между высокоуровневым программированием и лежащим в основе аппаратным обеспечением, охватывая машинное представление, архитектуру процессора, иерархию памяти и параллельное программирование.
Освойте искусство системного программирования, поняв интерфейс аппаратное-программное обеспечение.
Автор: Рэндал Э. Брайант, Дэвид Р. О’Холларон
Благодарности: Поддержка со стороны студентов и преподавателей курса 15-213 в Карнеги-Меллонском университете. Благодарности включают вклады Манасы С. и Мохита Тахилани.
🎯 Цели обучения
- Определить, как информация представляется с помощью битов и контекста внутри системы.
- Протрассировать четыре этапа компиляционной системы от исходного кода до исполняемого файла.
- Описать организационную структуру аппаратного обеспечения и иерархическую природу устройств хранения.
- Преобразовывать между десятичной, двоичной и шестнадцатеричной системами счисления и объяснить машинно-уровневое адресование (порядок байтов).
- Выполнять побитовые и логические операции на языке С и предсказывать результаты арифметических сдвигов.
- Анализировать кодировки целых чисел для выявления потенциальных уязвимостей переполнения и ошибок приведения типов.
- Анализировать соответствие между конструкциями на С (циклы, ветвления, процедуры) и инструкциями на языке ассемблера x86-64.
- Разбирать стек времени выполнения для объяснения передачи параметров, хранения локальных переменных и управления рекурсивными вызовами.
- Оценивать распределение памяти для гетерогенных структур данных и применять правила выравнивания для расчета общих требований к хранилищу.
- Определять видимое состояние программиста для Y86-64 и кодировать/декодировать инструкции в последовательности байтов.
🔹 Урок 1: Обзор компьютерных систем
Обзор: Этот урок предоставляет всесторонний обзор того, как компьютерные системы представляют информацию, переводят программы и выполняют инструкции через сложные взаимодействия аппаратного и программного обеспечения. Он исследует путь программы от исходного кода до выполнения, ключевую роль иерархии памяти в преодолении разрыва между процессором и памятью, абстракции, предоставляемые операционной системой, и математические законы, регулирующие производительность системы и параллелизм.
Результаты обучения:
- Определить, как информация представляется с помощью битов и контекста внутри системы.
- Протрассировать четыре этапа компиляционной системы от исходного кода до исполняемого файла.
- Описать организационную структуру аппаратного обеспечения и иерархическую природу устройств хранения.
🔹 Урок 2: Представление и манипулирование информацией
Обзор: В этом уроке рассматривается, как цифровые компьютеры представляют и манипулируют информацией на уровне битов. Охватывается переход от шестнадцатеричной записи и размеров слов на машинном уровне к сложным кодировкам целых чисел (беззнаковые и дополнительный код) и чисел с плавающей точкой (стандарт IEEE 754). Студенты анализируют математические свойства компьютерной арифметики, включая последствия переполнения для безопасности и нюансы округления в системах с конечной точностью.
Результаты обучения:
- Преобразовывать между десятичной, двоичной и шестнадцатеричной системами счисления и объяснять машинно-уровневое адресование (порядок байтов).
- Выполнять побитовые и логические операции на языке С и предсказывать результаты арифметических сдвигов.
- Анализировать кодировки целых чисел для выявления потенциальных уязвимостей переполнения и ошибок приведения типов.
🔹 Урок 3: Машинное представление программ
Обзор: В этом уроке представлено подробное изучение того, как высокий уровень программ на С трансформируется в машинный код для архитектуры x86-64. Охватываются фундаментальные архитектурные особенности процессора, включая регистры и стек, реализация управления потоком (условные выражения, циклы и переключатели), механизмы вызовов процедур и рекурсии, а также машинное представление сложных структур данных, таких как массивы, структуры и объединения. В заключение рассматриваются вопросы безопасности системы через анализ переполнения буфера и специализированные инструкции для арифметики с плавающей точкой.
Результаты обучения:
- Анализировать соответствие между конструкциями на С (циклы, ветвления, процедуры) и инструкциями на языке ассемблера x86-64.
- Разбирать стек времени выполнения для объяснения передачи параметров, хранения локальных переменных и управления рекурсивными вызовами.
- Оценивать распределение памяти для гетерогенных структур данных и применять правила выравнивания для расчета общих требований к хранилищу.
🔹 Урок 4: Архитектура процессора
Обзор: В этом уроке рассматривается фундаментальная архитектура процессора, с акцентом на переход от последовательной реализации (SEQ) к высокопроизводительной конвейерной реализации (PIPE) с использованием архитектуры набора инструкций Y86-64. Студенты анализируют, как инструкции кодируются, обрабатываются по дискретным этапам (Выборка, Декодирование, Выполнение, Память, Запись результата) и как аппаратные опасности управляются с помощью логики управления, задержки и передачи данных для максимизации пропускной способности.
Результаты обучения:
- Определить видимое состояние программиста для Y86-64 и кодировать/декодировать инструкции в последовательности байтов.
- Реализовать логику управления аппаратным устройством с помощью языка HCL (Hardware Control Language) для комбинаторных и последовательных схем.
- Протрассировать поток инструкций через шесть этапов последовательного процессора и определить влияние тактирования.
🔹 Урок 5: Оптимизация производительности программ
Обзор: В этом уроке рассматривается системный подход к повышению производительности программ, основанный на понимании взаимодействия между высокоуровневым кодом, оптимизирующими компиляторами и современными микропроцессорными архитектурами. Студенты научатся выявлять "блокеры оптимизации", такие как алгебраическое перекрытие памяти, применять низкоуровневые преобразования, такие как развертывание циклов и переупорядочивание, и использовать инструменты профилирования, такие как GPROF, для эффективного выявления узких мест производительности.
Результаты обучения:
- Определять и устранять блокеры оптимизации, включая перекрытие памяти и накладные расходы на вызов процедур.
- Количественно оценивать производительность программы с помощью метрики "Циклов на элемент" (CPE).
- Применять преобразования развертывания циклов, нескольких аккумуляторов и переупорядочивания для использования параллелизма на уровне инструкций.
🔹 Урок 6: Иерархия памяти
Обзор: В этом уроке рассматривается структурная и функциональная организация иерархии памяти, с акцентом на компромиссы между скоростью, стоимостью и емкостью хранения. Подробно описываются технологии, лежащие в основе современных систем — от SRAM и DRAM до дисков и SSD — и объясняется, как Принцип локальности (временной и пространственный) позволяет маленьким, быстрым кэш-памятьям значительно улучшать производительность программ. Студенты научатся анализировать методы отображения кэша (прямое отображение, множественная ассоциативность, полная ассоциативность) и применять техники оптимизации, такие как перестановка и блокировка циклов, чтобы писать код, совместимый с кэшем.
Результаты обучения:
- Различать технологии памяти SRAM, DRAM, ROM и флэш-памяти и их роли в иерархии.
- Вычислять емкость дискового хранилища и общее время доступа на основе геометрии и рабочих компонентов.
- Анализировать адреса памяти для определения индексов наборов кэша, тегов и смещений блоков при различных стратегиях отображения.
🔹 Урок 7: Связывание
Обзор: В этом уроке рассматривается критически важный системный процесс связывания, который объединяет код и данные в один файл, который может быть загружен в память и выполнен. Студенты переходят от исходного кода к исполняемым бинарникам, понимая, как связывальщик разрешает ссылки на символы, объединяет секции с помощью перераспределения и управляет как статическими, так и динамическими библиотеками. Урок завершается продвинутыми техниками, такими как интерпозиция библиотек и код без привязки к положению (PIC), используемые в современных общих библиотеках.
Результаты обучения:
- Протрассировать трансформацию исходных файлов через драйвер компилятора до конечного исполняемого файла.
- Анализировать объектные файлы формата ELF для определения типов символов и организации секций.
- Применять правила разрешения символов для управления дублирующимися именами и зависимостями на этапе связывания.
🔹 Урок 8: Исключительный поток управления
Обзор: В этом уроке рассматривается Исключительный поток управления (ECF) — механизм, с помощью которого компьютерная система реагирует на изменения состояния системы. Мы изучаем, как реализуется ECF на всех уровнях системы: аппаратные исключения, переключение контекста и управление процессами (fork, wait, execve) на уровне операционной системы, а также сигналы и нелокальные переходы на уровне программного обеспечения. Студенты научатся управлять параллельностью, обрабатывать системные ошибки и писать надежный, безопасный сигналами код.
Результаты обучения:
- Различать четыре класса аппаратных исключений (прерывания, трэпы, сбои, аварии) и их механизмы обработки.
- Управлять жизненным циклом процессов с помощью системных вызовов создания (
fork), сбора (waitpid) и выполнения (execve). - Реализовывать безопасные обработчики сигналов, учитывающие параллельность, непоследовательность сигналов и безопасность при асинхронных сигналах.
🔹 Урок 9: Виртуальная память
Обзор: В этом уроке рассматривается Виртуальная память (VM) как фундаментальная абстракция, предоставляющая каждому процессу большой, непрерывный и частный адресное пространство. Рассматриваются три основные функции: средство для эффективного кэширования в памяти DRAM, механизм управления и защиты памяти, а также основа для маппинга памяти. Кроме того, урок затрагивает механику перевода адресов (TLB), динамическое выделение памяти (управление кучей) и принципы автоматической сборки мусора, завершаясь критическими ошибками, связанными с памятью в программировании на языке С.
Результаты обучения:
- Различать физическое и виртуальное адресное пространство и описывать роль Модуля управления памятью (MMU).
- Выполнять перевод виртуального адреса в физический с помощью таблиц страниц и буфера переводов (TLB).
- Анализировать и реализовывать стратегии динамического выделения памяти, включая неявные/явные списки и слияние.
🔹 Урок 10: Системный ввод-вывод
Обзор: В этом уроке рассматривается фундаментальный интерфейс между операционной системой Linux и приложениями для выполнения ввода-вывода. Охватываются базовые системные вызовы Unix I/O, различные типы файлов, встречающихся в файловой системе Linux, и структуры данных на уровне ядра, используемые для их управления. Кроме того, вводится пакет Robust I/O (RIO) для работы с "неполными чтениями" и даются рекомендации по выбору между стандартным вводом-выводом и системным вводом-выводом в различных контекстах программирования, таких как сетевое программирование.
Результаты обучения:
- Реализовывать базовые операции с файлами с помощью интерфейса Unix I/O (
open,close,read,write). - Различать обычные файлы, директории и ссылки, а также запрашивать метаданные файла с помощью
stat. - Использовать пакет RIO для выполнения надежных, буферизованных и небуферизованных операций ввода-вывода.
🔹 Урок 11: Сетевое программирование
Обзор: В этом уроке рассматривается фундаментальная архитектура сетевых приложений, основанная на модели клиент-сервер и глобальной интернет-сети на основе протокола IP. Студенты узнают, как работать с интерфейсом сокетов — основным API для системного сетевого взаимодействия, и продвигаются к реализации функционального веб-сервера (TINY), способного доставлять как статические файлы, так и динамический контент через общий интерфейс программирования (CGI).
Результаты обучения:
- Понимать цикл запрос-ответ модели клиент-сервер и аппаратно-программную иерархию глобальной интернет-сети на основе протокола IP.
- Манипулировать и преобразовывать IP-адреса, доменные имена и структуры сокетов с помощью протокольно-независимых функций, таких как
getaddrinfo. - Реализовывать надежный итеративный веб-сервер и программы CGI, использующие управление процессами и перенаправление ввода-вывода для обслуживания динамического контента.
🔹 Урок 12: Параллельное программирование
Обзор: В этом уроке рассматриваются фундаментальные модели параллелизма: процессы, многозадачность ввода-вывода и потоки. Предоставляется глубокое изучение синхронизации с помощью семафоров для решения гонок, распространённые архитектурные шаблоны, такие как производитель-потребитель и предварительно созданные серверы, и метрики, используемые для оценки параллельной производительности. В заключение рассматриваются критические вопросы надежности, включая безопасность потоков, повторяемость и предотвращение зависаний.
Результаты обучения:
- Различать модели параллелизма, основанные на процессах, многозадачности ввода-вывода и потоках.
- Применять операции семафоров (P и V) для обеспечения взаимного исключения и решения шаблонов синхронизации.
- Вычислять метрики параллельной производительности, такие как ускорение и эффективность, при разных законах масштабирования.