システムイメージの作成

Julia システムイメージの作成

Julia は Base モジュールが含まれる準備済みシステムイメージ sys.jl と共に配布されます。このファイルは可能な限り多くのプラットフォームで共有ライブラリ sys.{so,dll,dylib} へと事前コンパイルされ、これによってスタートアップ時間が大幅に短縮されます。Julia システムに事前コンパイルされたシステムイメージファイルが付属しないときは、Julia の DATAROOTDIR/julia/base フォルダーにあるソースファイルからコンパイルされたイメージファイルを生成できます。

システムイメージの作成が便利な理由はいくつかあります。ユーザーは次のことが行えます:

PackageCompiler.jl パッケージにはこの処理を自動化するための便利なラッパー関数が含まれます。

複数のマイクロアーキテクチャに対応したシステムイメージ

同じ命令セットアーキテクチャ (ISA) を持つ異なる複数の CPU マイクロアーキテクチャに対応したシステムイメージをまとめてコンパイルすることが可能です。全てのアーキテクチャで共有の関数に挿入された最小限のディスパッチ処理を使って同じ関数の異なるバージョンを呼び出せるようにすることで、ISA 拡張などのマイクロアーキテクチャの機能の活用できます。実行時には利用可能なCPU 機能に基づいて最も優れた性能を出すバージョンが自動的に選択されます。

複数のシステムイメージターゲットの指定

複数のマイクロアーキテクチャに対応したシステムイメージを有効化するには、システムイメージをコンパイルするときに複数のターゲットを指定します。これは make の JULIA_CPU_TARGET オプションまたはコンパイルを手動で実行するときのコマンドライン引数 -C で行います。ターゲットを指定する構文は CPU の名前に , で区切った機能の名前を並べるというもので、複数のターゲットは ; で区切ります。LLVM がサポートする全ての機能がサポートされ、先頭に - を付ければ無効化できます (LLVM の構文に合わせて + を先頭に付けても構いませんが、無視されます)。また関数のクローンを制御するための特別な機能がいくつかサポートされます:

例えば執筆時点において、https://julialang.org/ からダウンロードできる x86_64 に対する Julia バイナリは次の文字列を使って作成されています:

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

この文字列は三つのターゲットを持ったシステムイメージを作成します: 一つは x86_64 プロセッサに対する汎用的なもの、一つは全ての関数を明示的にクローンする (そしてxsaveopt を用いない) sandybridge ISA に対するもの、最後の一つは sandybridge のシステムイメージバージョンをベースとして rdrnd を除いた haswell ISA に対するものです。生成されたシステムイメージを読み込む Julia 実装は最初にホストプロセッサを確認して適合する CPU 機能フラグを調べ、最も上位の ISA レベルを有効化します。ベースレベル (generic) が cx16 命令を必要とすることに注意してください。一部の仮想化ソフトウェアはこの命令を無効化しているので、このシステムイメージを読み込むには手動で有効化する必要があります。この代わりに generic,-cs16 をターゲットとしてシステムイメージを生成すれば互換性が向上しますが、性能や安定性の問題が発生する可能性があります。

実装の概要

実装に関連する様々な要素を簡単に説明します。それぞれの要素についてさらに詳しくはコードのコメントを参照してください。

  1. システムイメージのコンパイル

    コードのパースと関数のクローンの判断は src/processor* で行われます。クローンの判断にはループ・SIMD 命令・その他の数学演算 (fastmath, fma, muladd) の有無が使われ、この情報は実際のクローンを行う src/llvm-multiversioning.cpp に渡されます。クローンとディスパッチスロットの追加がどのように行われるかは MultiVersioning::runOnModule のコメントを参照してください。これに加えて、このパスはランタイムがシステムイメージの読み込みと初期化を正しく行うためのメタデータの生成も行います。利用可能なメタデータの詳細な説明は src/processor.h にあります。

  2. システムイメージの読み込み

    システムイメージの読み込みと初期化はシステムイメージを生成するときに保存されたメタデータを src/processor* にあるコードでパースすることで行われます。ホストが持つ機能の検出と選択は ISA に基づいて src/processor_*.cpp で行われます。ターゲットの選択では大きなベクトルレジスタサイズや機能の数よりも CPU 名の完全なマッチが優先されます。この処理の概要は src/processor.cpp にあります。