Документация Engee

Сборка образа системы

Сборка образа системы Julia

В состав Julia входит предварительно проанализированный образ системы с содержимым модуля Base с именем sys.ji. Этот файл также предварительно скомпилирован в общую библиотеку sys.{so,dll,dylib} для максимально возможного количества платформ, чтобы значительно улучшить время запуска. В системах, которые не поставляются с предварительно скомпилированным файлом образа системы, этот файл может быть сгенерирован из файлов исходного кода, находящихся в папке DATAROOTDIR/julia/base Julia.

Эта операция полезна по нескольким причинам. Пользователь может выполнить следующие задачи.

  • Собрать предварительно скомпилированный образ системы общих библиотек на платформе, которая не поставляется с таким образом, тем самым улучшая время запуска.

  • Изменить модуль Base, повторно собрать образ системы и использовать новый модуль Base при следующем запуске Julia.

  • Включить файл userimg.jl, который содержит пакеты, в образ системы, тем самым создавая образ системы, в котором пакеты внедрены в среду запуска.

Пакет PackageCompiler.jl содержит удобные функции-оболочки для автоматизации этого процесса.

Образ системы, оптимизированный для нескольких микроархитектур

Образ системы может быть скомпилирован одновременно для нескольких микроархитектур ЦП в одной и той же архитектуре набора инструкций (ISA). Можно создать несколько версий одной и той же функции с минимальной точкой диспетчеризации, вставленной в общие функции, чтобы использовать преимущества различных расширений ISA или других возможностей микроархитектуры. Версия, обеспечивающая наилучшую производительность, будет выбрана автоматически во время выполнения на основе доступных характеристик ЦП.

Указание нескольких целевых объектов образа системы

Образ системы с несколькими микроархитектурами может быть включен путем передачи нескольких целевых объектов время компиляции образа системы. Это можно сделать либо с помощью параметра создания JULIA_CPU_TARGET, либо с помощью параметра -C командной строки при выполнении команды компиляции вручную. Несколько целевых объектов разделяются в строке параметров символом ;. Синтаксис для каждого целевого объекта представляет собой имя ЦП, за которым следует несколько функций, разделенных символом ,. Поддерживаются все функции, поддерживаемые LLVM. Функцию можно отключить с помощью префикса -. (Префикс + также разрешен и игнорируется для согласования с синтаксисом LLVM.) Кроме того, поддерживается несколько специальных функций для управления поведением клонирования функций.

Рекомендуется указывать либо clone_all, либо base(<n>) для каждой целевой платформы, а не только для первой. Это позволяет явным образом сообщить, для каких целевых платформ будут клонированы все функции и какие целевые платформы основаны на других целевых платформах. Если не сделать этого, по умолчанию будут клонироваться не все функции, причем в случае, если функция не клонируется, в качестве резервного варианта будет использоваться определение функции для первой целевой платформы.

  1. clone_all

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

  2. base(<n>)

    <n> — это местозаполнитель для неотрицательного числа (например, base(0), base(1)). По умолчанию частично клонированный (т. е. без clone_all) целевой объект будет использовать функции из целевого объекта по умолчанию (первого указанного), если функция не клонирована. Это поведение можно изменить, указав другую основу с помощью параметра base(<n>). n-й целевой объект (на основе 0) будет использоваться в качестве базового целевого объекта вместо стандартного (0-го). Базовый целевой объект должен быть либо 0, либо другим целевым объектом clone_all. Указание целевого объекта, отличного от clone_all, в качестве базового приведет к ошибке.

  3. opt_size

    В результате функция для целевого объекта будет оптимизирована по размеру, что не оказывает значительного влияния на производительность во время выполнения. Это соответствует параметру -Os GCC и Clang.

  4. min_size

    В результате функция для целевого объекта будет оптимизирована по размеру, что может оказать значительное влияние на производительность во время выполнения. Это соответствует параметру -Oz Clang.

Например, на момент написания этого документа при создании официальных двоичных файлов x86_64 Julia, скачиваемых с сайта julialang.org, используется следующая строка.

generic;sandybridge,-xsaveopt,clone_all;haswell,-rdrnd,base(1)

При этом создается образ системы с тремя отдельными целевыми объектами: один для универсального процессора x86_64, один с sandybridge ISA (явно исключая xsaveopt), который явным образом клонирует все функции, и один, предназначенный для haswell ISA, основанный на версии sysimg sandybridge и также исключающий rdrnd. Когда реализация Julia загружает сгенерированный sysimg, она проверяет ведущий процессор на наличие соответствующих флагов возможностей ЦП, позволяющих использовать самый высокий уровень ISA. Обратите внимание, что для базового уровня (generic) требуется инструкция cx16, которая отключена в некоторых программах виртуализации и должна быть включена для загрузки целевого объекта generic. В качестве альтернативы можно сгенерировать sysimg с целевым объектом generic,-cx16 для большей совместимости. Однако следует учесть, что это может привести к проблемам с производительностью и стабильностью в некоторых кодах.

Обзор реализации

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

  1. Компиляция образа системы

    Анализ и клонирование выполняются в src/processor*. В настоящее время поддерживается клонирование функции на основе наличия циклов, инструкций simd или других математических операций (например, fastmath, fma, muladd). Эта информация передается в файл src/llvm-multiversioning.cpp, который выполняет фактическое клонирование. Помимо клонирования и вставки слотов диспетчеризации (о том, как это делается, см. в комментариях в MultiVersioning::runOnModule), передача также генерирует метаданные, чтобы среда выполнения могла правильно загрузить и инициализировать образ системы. Подробное описание метаданных доступно в файле src/processor.h.

  2. Загрузка образа системы

    Загрузка и инициализация образа системы выполняется в src/processor* путем анализа метаданных, сохраненных при генерации образа системы. Определение основных функций и их выбор осуществляются в файле src/processor_*.cpp в зависимости от ISA. При выборе целевого объекта рекомендуется придерживаться точного соответствия имени ЦП, а также выбрать большой размер векторного регистра и большее количество функций. Обзор этого процесса приведен в файле src/processor.cpp.