intel®software

THE PARALLEL

UNIVERSE

データ並列 C++ を使用して2 次元熱伝導方程式を解く
インテル® DPC++ 互換性ツールを使用した
CUDA* から DPC++ への移行
GPU オフロードコードのメモリーとスレッドの正当性解析

00001101
00001010
00001101
00001010
01001100
01101111
01110010
Issue
01100101
01101101
00100000
2021
01101000
01110001
01110011
01110101

43

目次

2

The Parallel Universe

編集者からのメッセージ
2021 年が実り多き年になりますように

3

データ並列 C++ を使用して 2 次元熱伝導方程式を解く

5インテル® DPC++ 互換性ツールを使用した CUDA* から DPC++ への移行

23

GPU オフロードコードのメモリーとスレッドの正当性解析

29

注目記事

Henry A. Gabb インテル コーポレーション シニア主席エンジニア

C と MPI アプリケーションを DPC++ に移行するステップバイステップのケーススタディー

独自仕様でないプログラミング言語への移行がさらに容易にインテル® Inspector でヘテロジニアス並列コードを簡単にデバッグ

インテル® コンパイラーの最適化レポートを使用してチューニングの可能性を見つける40

インテル® MPI ライブラリーを使用したクラスター全体の MPI チューニング

48

マシンラーニング向け線形モデルの高速化

56

XGBoost と LightGBM 推論パフォーマンスの向上

64

コード生成、 プロシージャー間の最適化、 浮動小数点精度など

mpitune_fast ユーティリティーを使用した MPI 集合通信のチューニング

線形回帰がこれまでになく高速にインテル® oneAPI データ ・アナリティクス ・ ライブラリーにより推論を最大 36 倍高速化

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

3

編集者からのメッセージ
Henry A. Gabb インテル コーポレーション シニア主席エンジニア
HPC と並列コンピューティング分野で長年の経験があり、 並列プログラミングに関する記事を
多 数 出 版 し て い ま す。 『Developing Multithreaded Applications ： A Platform ConsistentApproach』 の編集者 / 共著者で、 インテルと Microsoft* による Universal Parallel Computing
Research Centers のプログラム ・ マネージャーを務めました。

2021 年が実り多き年になりますように
2021 年最初の The Parallel Universe へようこそ
oneAPI イニシアチブ （英語） は、 v1.0 仕様 （英語） のリリース後も、 業界と学界で引き続き高い評価を得ています。 SC20 と oneAPI デベロッパー ・ サミットでは最 新の 情 報を 発表して、 2020 年 を締めくくりました（コンテンツはオンライン （英語） で利用できます）。 oneAPI アプリケーション ・ カタログ （英語） では、 200
社が開発した 240 のアプリケーションが公開されました。 さまざまな業界およびアプリケーション ・ カテゴ
リーの oneAPI アプリケーションが掲載されています。 大学および学生と oneAPI イニシアチブの結び付きを支援するインテル® Academic Program for oneAPI （英語） も開始されました。 最後に、 新しい書籍、『Data Parallel C++ ： Mastering DPC++ for Programming of Heterogeneous Systems Using C++ andSYCL （データ並列 C++ ： C++ と SYCL* を使用したヘテロジニアス ・ システムのプログラミングで DPC++を使いこなす）』 （英語） が Apress から出版されました。 The Parallel Universe の創刊者兼編集者であった
James Reinders も共同執筆しています。 James と言えば、 ヘテロジニアス並列プログラミングに対する
oneAPI アプローチを促進するためインテルに復帰したことを、 この機会にお知らせします。
今号では、 oneAPI の人気の高まりを受けて、 科 学計算アプリケーションの移植ケース スタディー、 「データ並列 C++ を使用して 2 次元熱伝導方程式を解く」 を注目記事として取り上げました。 さらに、 2 つのチュー
トリアル、 「インテル® DPC++ 互換性ツールを使用した CUDA* から DPC++ への移行」 と 「GPU オフロード
コードのメモリーとスレッドの正当性解析」 が続きます。 これらの 3 つの記事は、 DPC++ プログラミングを始めるのに役立ちます。
次に、 コードの現代化とハイパフォーマンス ・ コンピューティングの記事として、 コンパイラー最適化レポートの活用と MPI アプリケーションのチューニングに関するシリーズ、 「インテル® コンパイラーの最適化レポートを使用してチューニングの可能性を見つける」 と 「インテル® MPI ライブラリーを使用したクラスター全体の MPI
チューニング」 が続きます。 これらの記事では、 コードをほとんど変更することなくパフォーマンスを向上する簡単な方法を紹介します。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

4

そして本号を締めくくるのは、 データ解析アプリケーションのマシンラーニング ・ パフォーマンスの向上に関する 2 つの記事です。 「マシンラーニング向け線形モデルの高速化」 と 「XGBoost と LightGBM 推論パフォーマンスの向上」
では、 Python* 向けインテル® ディストリビューションを使用してモデルのトレーニングと推論を最適化する方法を紹介します。 この 2 つの記事はどちらも、 データサイエンス向けのインテル® ソフトウェアを取り上げている、Medium – Intel Analytics Software （英語） で公開されている記事を再掲したものです。
コードの現代化、 ビジュアル ・ コンピューティング、 データセンターとクラウド ・ コンピューティング、 データ
サイエンス、 システムと IoT 開発、 oneAPI を利用したヘテロジニアス並列コンピューティング向けのインテルのソリューションの詳細は、 Tech.Decoded （英語） を参照してください。
Henry A. Gabb
2021 年 1 月

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe5

データ並列 C++ （DPC++） を使用して2 次元熱伝導方程式を解く
C と MPI アプリケーションを DPC++ に移行するステップバイステップのケーススタディー

Graham McKenzie インテル コーポレーション システム ・ フィールド ・ アプリケーション ・ エンジニア

熱伝導方程式は並列コンピューティングのチュートリアルでよく使用される問題です。 この記事も、 Partnershipfor Advanced Computing in Europe （PRACE） により公開されている演習の 1 つから始めます。 オリジナルの
コード1 は、シングル・ポイント・ステンシルに離散化される 2 次元熱伝導方程式の C と MPI による実装です（図 1）。
2 次元平面はセルに分割され、 各セルは、 そのセルおよび隣接する 4 つのセルの以前の値に基づいて時間
ステップごとに更新されます。 問題の詳細な説明は、 PRACE リポジトリー 2 を参照してください。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

16

2 次元熱伝導方程式とシングル ・ ポイント ・ ステンシル

デフォルトの実装は、 500 時間ステップ処理する 2000 x 2000 セル平面から開始します （図 2）。 平面は、 均一
温度が異なる中央の円を除いて、均一温度に初期化されます。 外枠（エッジ）は 4 つの異なる温度で固定されます。

2

計算の設定

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

7

この記事では、 標準 C/C++ で記述されたコードに、 いくつかの簡単な DPC++ 構文を追加して、 異なる並列処理ユニットで実行する方法を説明します。 DPC++、SYCL*、および oneAPI の使用経験があると理解しやすいでしょう。

DPC++ への最初の移行
オリジナルの PRACE コードは、 MPI 構文を使用して、 問題を複数のプロセッサーと複数のノードで処理されるタ
イルに分割しています。 中心となる計算に取り組むため、 まずこの部分をコードから削除しました。 削除した部分は新たな並列処理を導入後コードに書き戻します。 問題を単純化するため、出力画像の定期的な書き込みやチェッ
クポイントの再開などの機能も削除しました。 最初と最後の平面を描写する画像の書き込みに関連するコードは、
機能検証ツールとして残しました。
最初に行った単純化は、 単一カーネルで平面全体を更新することでした。 MPI ベースのコードはエッジと内部を分離しているため、 ハローがほかのプロセスからコピーされている間に内部を更新できます。 1 つのタイルのエッジが、 隣接するタイルのハローになります。 ハローが更新されると、 ハローと内部の両方に依存するエッジを計算できます （図 3）。 この最初の移行作業では、 エッジと内部が 1 つとして扱われます。

3

データレイアウトと交換

DPC++ ヘッダーと名前空間
DPC++ を使用するには、 2 つのヘッダーファイルをインクルードする必要があります。 1 つ目のヘッダーファイル
は DPC++ コンパイラーで提供されるもので、 DPC++ 言語のサポートを提供します。 main.c、 core.c、 および
heat.h で参照されます。 2 つ目のヘッダーファイルは DPC++ サンプルプログラムのコレクション3 に含まれているもので、 例外ハンドラーのためにインクルードします。 main.c で参照されます。 さらに、 コード本体の SYCL*
構造を単純化するため、 sycl 名前空間を宣言します。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

8

その他の main.c に対する変更点は、 先頭と最後が DPC++ コードでラップされた時間反復ループを含みます。
次の 5 つのコードセグメントは連続したコードですが、 ここでは説明のために分割しています。

デバイスとキュー
デフォルトのセレクターを選択します。 これは、 ランタイムがカーネルを実行するターゲットデバイスを選択することを意味します。 通常は、 GPU が存在する場合は GPU が使用され、 GPU が存在しない場合はホスト CPU が使用されます。 特定のデバイスを使用する場合は、 default_selector の代わりに cpu_selector または
gpu_selector を使用します。 次に、 try-catch ブロックでラップされたセレクターと例外ハンドラーに基づいて queue を定義します。

バッファー
バッファーは、 ターゲットデバイスに存在し、 OpenCL* プログラマーに馴染みのあるデータのコンテナーを提供します。 オリジナルコードのデータ構造から、 ハローのため各次元に 2 つ （各サイドに 1 つ） のセルを追加して、問題のサイズを取得します （図 3）。 global_range をオリジナルのホスト配列の問題サイズと次元に基づいた
1 次元の範囲として宣言します。 次に、 この範囲とホストデータのポインターを参照するバッファーを定義します。

キューのサブミットとアクセサー
時間処理 for ループはオリジナルコードから変更していません。 ループの各反復で、 上記で定義されたキューに対しカーネルをサブミットします。 アクセサーは、 バッファーがデバイス上でアクセスされる方法を定義します。 このケースでは、両方のバッファーへの read_write アクセスを定義しています。 各ループ反復では、1 つのバッファーからのみ読み取り、 もう 1 つのバッファーへ書き込みを行いますが、 コンテキスト内でバッファーをスワップするため、 これらのバッファーを read または write として定義することはできません。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

9

カーネル実行
ここでは、 parallel_for カーネルを使用します。 このセクションの本体は、 問題のすべての項目 （平面のすべてのセル、 このケースではハローを含む） に対してサブミットされます。 計算しているセルを識別する、 カーネルに渡される 1 次元 ID、 id を定義します。 カーネル本体内のインデックス作成に役立つ 2 次元 ID を使用することもできますが、 最小限のコード変更で機能の移行を示すため、 ここでは 1 次元 ID を使用しました。 カーネルの本
体は、 後で説明する別のファイル core.c の evolve 関数内に含まれています。 オリジナルコードには、 同等のevolve 関数への呼び出しポインターがあり、 ループ内でポインターをスワップしています。 ここでは、 バッファーを管理しやすくするため、 個別の parallel_for 呼び出しを行い、 各ループ反復でアクセサーへのポインターを切り替えます。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

10

エラー処理
カーネルの実行中に発生したエラーはすべてホスト ・アプリケーション ・スコープに渡され、 従来の C++ 例外処理
で処理されます。 ここでは、 サンプルプログラムで提供されている標準例外ハンドラーを利用します。

カーネルコード
次のコードは、 core.c の完全なリストです。 プロセス間の通信や内部とエッジ計算の分離について考慮する必要がないため、 オリジナルコードから大幅に簡素化されています。 オリジナルコードでは、 従来の CPU プログラミン
グと同様に、 evolve 関数が平面全体に対して 1 回呼び出され、 ネストされた 2 つの for ループが x 次元と y

次元をトラバースして、 各セルの更新を計算しています。 上記の parallel_for 呼び出しを使用することで、 個々のセルで次の関数が呼び出されます。 そのため、 for ループは必要ありません。

parallel_for を呼び出すときに使用されるグローバル範囲にはハローが含まれています。 ハローは更新されませんが、 エッジの新しい値を計算するために必要です。 if 文を使用してハローを省略し、 バッファーの外でメモリーの読み取り （セグメンテーション違反が発生します） を行わないようにします。 実際の計算はコードの最後の行で行われており、 オリジナルコードと非常に似ています。 それ以外の中間変数は、 可読性を向上するために宣言されています。
関数のパラメーターは微 妙に変更されています。 最も明白な変更点は、 計算しているセルを識別するために必要な ID が含まれていることです。 また、 dx と dy ではなく、 dx2 と dy2 をカーネルに渡しています。
dx2 と dy2 は元々カーネルで計算されていましたが、 それらの値はすべてのセルで一定です。 新しい evolve関数はすべてのセルで呼び出されるため、 これらの値を毎回計算すると不要なオーバーヘッドが発生します。 また、本体からは明白でないため、 関数を SYCL_EXTERNAL として宣言して、 これがカーネルコードであることをコンパイラーに知らせる必要があります。 ヘッダーファイルの関数プロトタイプも、 これに応じて変更します。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe11

アプリケーションとカーネルのコンパイルオリジナルコードは mpicc コンパイラーを使用しています。DPC++ 向けにコンパイルするため、dpcpp コンパイラー
を使用するよう Makefile を変更します。 しかし、 PNG ファイルの書き込みに関連するファイルには C コンパイ
ラーが必要であるため、 GCC を使用して、 extern "C" {…} で関数プロトタイプをラップします。 これらのファ
イルは libpng 4 を参照します。 libpng は、 sudo apt-get install libpng-dev コマンドを使用してインストールするか、 ソースをダウンロードしてビルドします。

FPGA をターゲットにする
上記のコードと変更した Makefile は、 CPU と GPU をターゲットにしています。 FPGA をターゲットにするには、
ソースコードと Makefile を少し変更します。
main.c は、 FPGA が定義されているときに fpga_selector を選択するように変更します。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

12

Makefile に、コンパイラーとリンカー向けのオプションを追加します。 また、CPU/GPU バージョンと区別するため、実行ファイルの名前を変更します。

インテル® DevCloud でアプリケーションを実行
インテル® DevCloud5 は、 プ リインスト ールさ れ た 環 境 で oneAPI と DPC++ を 無 料で 試し、 さ まざ ま な
インテルの CPU、 GPU、 および FPGA テクノロジーを使用する機会をユーザーに提供します。 以下の説明は、インテル® DevCloud にアクセスして、 導入ガイド6 に従って設定済みであると仮定しています。
コードをコンパイルして実行する前に、 libpng をインストールする必 要があります。 インテル® DevCloudでは sudo アクセスを利用できないため、 ソースからコンパイルします。 「関連情報」 の 7 からソースコードをダウンロードしてインテル® DevCloud にコピーした後、 次の操作を行います。

次 に、 ~/.bashrc に 次のコマ ンド を 追 加 す るか、 新 し いセ ッ ション でこれ ら のコマ ンド を 実 行し ま す。
Makefile でライブラリーを参照するには、 LIBPNG_ROOT 環境変数を使用します。

熱伝導方程式をコンパイルして実行するには、 次のいずれかのコマンドを使用して、 CPU と GPU の関連する計算
ノードでインタラクティブなセッションを開始します。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

13

次に、 セッションを終了する前に、 コードを作成して実行します。

FPGA はコンパイルに時間がかかるため、 次のように FPGA コンパイルノードの 1 つをターゲットにして、バッチジョブとしてサブミットすることを推奨します。

また、 競合を避けるため、 CPU/GPU コンパイルと FPGA の間で make clean を行うか、 別のディレクトリー
でコンパイルすることを推奨します。 compile_fpga.sh の内容は次のとおりです。 ファイルは実行可能である
必要があります。

FPGA コンパイル向けに別の Makefile を保持していることに注意してください。 ジョブのステータスは qstat
コマンドを使用して確認できます。 正常に完了すると、 次のようにインタラクティブなセッションを開始して、カーネルを FPGA で実行できます。

動作の検証
実行の最後に、 ホスト ・ アプリケーションは特定のセルの最終値を端末に出力し、 最終平面の PNG 画像を出力します （図 4）。 特定の値で、 異なるコードの反復とカーネルターゲットに対するクイックチェックを行います。 この値は CPU、 GPU、 および FPGA の実行ですべて同じで、 オリジナルコードの値と一致します。 PNG 画像は、
サードパーティーのアプリケーションを使用して比較できます。 3 つのテクノロジーまたはオリジナルコードで違いはありません。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe4

14

シングルポイント検証

MPI 実装MPI マルチプロセスのサポートをコードに追加する前に、 ホストとデバイス間で問題を分割する方法と、 操作を並列化する方法を考える必要があります。 合理的な開始点は、ホストでエッジ計算とプロセス間の転送を処理し、デバイスで内部を計算することです。 これは、 オリジナルコードのアプローチと一致します。 時間反復ループ中で、各反復の終了時にポインターをスワップする前に、 同期ポイントを使用してエッジとは別に内部を処理できます（図 5）。 2 つの行は並列に実行できます。

5

各反復中のホストとデバイス間のデータ交換

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

15

The Parallel Universe

もう 1 つ考慮すべき重要な点は、 問題を MPI プロセス間でどのように分割するかです。 オリジナルコード
は、 2 次元分割を使用して、 4 つのプロセスで問題を 4 つの象限 （2 x 2 タイル） に分割しています。 ホストとデバイス間のデータ転送が複雑になり、 必要なデータのみ転送する場合でも、 左右のエッジに多くの 個別の PCIe* トランザクションが構成されます。 1 回の大きな転送は複数回の小さな転送よりも高速であるため、デバイスの内部処理の各反復間でデータ平面全体を転送する方が効率的です。 しかし、 より適切な方法は、問題を 1 次元で分割することです。 この方法では、 ホストとデバイス間で必要なデータのみ転送できます。
転送には 2 つの連続したメモリー （上下のエッジ） が必要になります （図 6）。 図 7 は、 すべてのデータの転送にかかる時間に正規化した相対実行時間を示しています。 この問題のグローバルエッジは固定であることに注意してください。 1 次元実装では左右のエッジを転送する必要がないため、 1D 分割と 2D 分割で転送されるデータの量は同じです。

6

1D データ分割と 2D データ分割

データ並列 C++

標準ベースのクロスアーキテクチャー言語

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

詳細
（英 語）

The Parallel Universe

7

16

相対実行時間setup.c の MPI_Dims_create 関数に渡す次元を変更するだけで、 1 次元分割を強制できます。 この関数にゼロを渡すと、 ランタイムが各次元の範囲を定義します。 2 つ目の値として 1 を使用して、 単一列実装を行います。

前の実装で使用したバッファー実装は、 実行前に暗黙的にデータをデバイスに転送して、 バッファーがコンテキストから出ると再度転送します。 ループ内でデータを転送できるようにするには、 細かい制御が必要です。
統合共有メモリー （USM） モデルを使用すると、 データをデバイス、 ホスト、 または共有として割り当て、 使い
慣れた C++ 構文でメモリーを処理することができます。 ここでは、 ホストとデバイス間のデータ転送を明示的に制御できる、 デバイスの割り当てメモリーを使用します。
オリジナルコードを開始点として、 すべての MPI コードを保持し、 次の変更を加えます。 ヘッダーと名前空間の変
更は、 以前と同じであるため、 ここでは省略しています。 次の 5 つのセクションは連続したコードを表しています。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

17

デバイスメモリーの割り当て
デバイスセレクターとキューは、 最初の実装と同じです。 バッファーを使用する代わりに、 malloc_device を使用してデバイスのメモリーを明示的に定義し、 memcpy 関数でコピーします。 デバイス ・コンテキストを提供するには、キューを参照する必要があります。 wait 関数は、 前のメモリー操作が完了するのを待ちます。 要求したアクション
をサブミットした後もホスト実行を継続してホストとアクセラレーター間の並列処理を可能にするには、 この関数が必要になります。 wait 関数は、 順不同で実行される可能性のあるキュー内のすべてのアクションが、 ホスト実行を継続する前に完了することを保証する同期ポイントとして機能します。 前の例では、 SYCL* ランタイムがバッファーを使用してスケジューリング操作を行っていました。

エッジをデバイスへコピー
各時間ステップの最初に、 各スライスの上下のエッジをポインター演算により識別してホストからデバイスにコピーします。 ハローを含むため、 コピーするエッジは上から 1 つ下の行と、 下から 1 つ上の行にあります。 コピーと交換を並列に実行できるように、 コピー、 交換の後に待機していることに注意してください。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

18

カーネル実行
この実装では、 デバイスは平面全体ではなく内部を処理するため、 計算の関数名を変更しています。 その他の微妙な違いは、 バッファーアクセサーのポインターの代わりにデバイスメモリーのポインターを渡していることです。
exchange_finalize はオリジナルコードに含まれている関数で、 エッジを処理する前に MPI ベースのデー
タ交換が完了するのを待ちます。 次に、 カーネルが完了するのを待った後、 内部のエッジをホストにコピーして戻します。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

19

ポインターのスワップ
各時間反復の最後のステップは、 ポインターのスワップです。 ホストでは、 オリジナルコードに含まれている
swap_fields 関数でこの処理を行います。 デバイスでは、 単純なポインターのスワップを実行します。

完了
カーネル操作を完了するため、 両方の平面をホストにコピーして戻し、 以前に割り当てられたデバイスメモリーを解放して、 例外をキャッチします。

カーネルコード
カーネルコードは、 以前の実装と非常に似ています。 唯一の違いは if 文で、 上下からはハローとエッジの両方を除外し、 左右のエッジからはハローのみ除外しています。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

20

追加の変更
左右のエッジはデバイスカーネルを使用して処理するようになったため、 evolve_edges 関数でホスト CPU からこの処理を削除する必要があります。 この関数は、 各エッジで 1 つ、 合計 4 つの for ループで構成されます。
左右のエッジは最後の 2 つで、 この部分をコメントアウトします。

MPI を使用したコンパイルと実行
dpcpp コンパイラーを使用し、 インテル® MPI ライブラリーのインクルードとリンクのオプションを追加します。

コードを実行するには、 mpirun を使用してプロセス数と実行ファイルを渡します。

シングルポイント値と PNG の両方を比較して、 この実装が以前の実装およびオリジナルコードと機能的に一致することを確認します。 複 数のプロセスを単一ノードで実行する場合、 および 複 数の GPU を使用して複数のノード間で実行する場合も同様です。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

21

The Parallel Universe

まとめ
コードにいくつかの基本的な変更を加えることで、 標準的な問題を解決し、 バッファーとアクセサーを使用した
DPC++ 実装に変換することができました。 インテル® DevCloud を使用して、 コードをコンパイルして CPU、GPU、 および FPGA を含む複数のターゲットで実行できます。 結果は、 オリジナルの実装と機能的に同じです。
最後に、 MPI を使用して複数のプロセス間のデータフローを管理するために必要なホストとデバイス間のメモリー転送を、 USM を使用して明示的に制御する方法を示しました。

関連情報 （英語）
1. PRACE の MPI と C を使用した 2 次元熱伝導方程式の MPI 実装
2. PRACE の 2 次元熱伝導方程式の説明
3. oneAPI ダイレクト ・ プログラミングのサンプル
4. LibPNG
5. インテル® DevCloud
6. インテル® DevCloud スタートガイド
7.

LibPNG ソースコード

NEWS HIGHLIGHTS
インテルが XPU ソフトウェア開発向けインテル® oneAPI ツールキットをリリース
インテルは、 インテルの CPU、 GPU、 FPGA でハイパフォーマンスなアプリケーション開発を簡素化する
インテル® oneAPI ツールキット 2021.1 をリリースしました。 開発ツールにおけるインテルの長年の実績と豊富な経験を標準化されたオープンなクロスアーキテクチャー ・プログラミング ・ モデルと組み合わせることで、 開発者が経済的および技術的な負担を伴う独自のプログラミング・モデルに縛られることなく、
特定のワークロードに最適なハードウェアを自由に選択できるようにします。
この記事の続きはこちらでご覧になれます。 >コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

oneAPI で複数のアーキテクチャーにわたる
多様なワークロードに妥協のない
パフォーマンスを提供

詳細 >コンパイラーの最適化に関する詳細は、最適化に関する注意事項（software.intel.com/en-us/articles/optimization-notice#opt-jp）を参照してください。
Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国における Intel Corporation またはその子会社の商標です。
© Intel Corporation

The Parallel Universe

23

インテル® DPC++ 互換性ツールを使用した CUDA* から DPC++ への移行
独自仕様でないプログラミング言語への移行がさらに容易にSubarnarekha Ghosal インテル コーポレーション コンパイラー ・ テクニカル ・ コンサルティング ・ エンジニア

将来のコンピューティング ・ システムはヘテロジニアスになることが明白になりつつあります。 テネシー大学のMAGMA （英語） プロジェクトは、 LAPACK に似ていますが、 最新の CPU および GPU システムを含むヘテロジニアス ・ アーキテクチャー向けの密線形代数ライブラリーを開発しています。 異なるアーキテクチャーで優れたパフォーマンスを提供するスパースソルバーのコードサンプルを探していたとき、 MAGMA は有力な候補でした。 この記事では、 インテル® DPC++ 互換性ツール （DPCT） を使用して MAGMA の CUDA* コードを
データ並列 C++ （DPC++） に移行する方法を説明します。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe24

移行手順と必要な変更移行する方法は 2 つあります。 1 つ目の方法は、 ファイルからファイルへの手動移行で、 わずかなファイルを移行する
場合に適しています。 2 つ目の方法は、 make または cmake を使用するプロジェクト向けの .json ファイルを作成することです。 MAGMA には makefile が用意されているため、 JSON アプローチを利用します。
入力プロジェクト ・ファイルのビルドオプション （インクルード ・ パス、 マクロ定義など） は、 intercept-build
make コマンドを使用して .json ファイルに格納します （Make 4.0 以降を使用していることを確認してください）。
次に、 dpct コマンドを実行します。 このコマンドには、 移行に役立つオプションが用意されています。 MAGMAを移行するためのコマンドラインは次のとおりです。

表 1. オプションと説明

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

25（その他のオプションは、 コマンドライン ・ オプション ・ リファレンス （英語） を参照してください。）
次のステップは、 アプリケーションで dpct を実行した後の出力を解釈することです。 dpct は、 コードを DPC++準拠にする、 または構文的に正しくするため変更が必要な可能性のある場所に注釈を付けます。

大規模なプロジェクトの場合、 移行ログをファイルにリダイレクトすることを推奨します。 ツールでレポートされる
エラーコード / 診断の詳細は、 こちら （英語） を参照してください。
図 1 と 図 2 は、 MAGMA ラ イ ブ ラ リ ー か ら の カ ー ネ ル 呼 び 出 し の 正 常 な 移 行 を 示 し て い ま す。
--keep-original-code オプションを使用しているため、オリジナルコードも移行後のファイルに存在します （図 2）。

1

オリジナル CUDA* コード

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

2

26

移行後の DPC++ コード

ツールが移行できない関数は手動で移行する必要がありますが、 その際、 ツールにより生成される注釈が参考になります。

CUDA* コードの 1 つの行に対して複数の注釈が生成されることがあります。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

27

The Parallel Universe

一部の CUDA* ライブラリーには、 oneAPI ライブラリー （oneMKL、 oneDNN、 oneVPL など） と同等の機能があります。 インテル® DPC++ 互換性ツールは、 多くの CUDA* ライブラリー関数を同等の oneAPI 関数に移行できます。 直接移行できない関数は明示されます。 多くの場合、 同じ機能を手動で実装できます。 例えば、 CUDA*
cusparseDcsrmv 関数は、 oneMKL mkl::sparse::gemv 関数と mkl::sparse::set_csr_data 関数
を組み合わせて手動で移行できます。
インテル® DPC++ 互換性ツールは、 ユーザーからのフィードバックにより日々進化しています。 ツールの既知の問題は、 リリースノート （英語） の 「既知の問題と制限事項」 セクションに記載されています。
インテル® DPC++ 互換性ツールは、 CUDA* アプリケーションを DPC++ に移行するために必要な時間と労力を軽減します。 ツールで移行されないコードのセクションで必要な手動の作業を最小限に抑えるために、 役立つ注釈と警告を提供します。 MAGMA の CUDA* から DPC++ への移行は、 このツールがなければ、 うんざりする作業だったでしょう。
CUDA* アプリケーションの DPC++ への移行に興味があるユーザー向けに、 オンライン ・ トレーニング （英語） も提供されています。 インテル® DPC++ 互換性ツールは、 インテル® oneAPI ベース ・ ツールキット （英語） に含まれています。

NEWS HIGHLIGHTS
ニジニ・ノヴゴロドのロバチェフスキー大学が oneAPI を使用して量子プロセスの研究を高速化ニジニ・ノヴゴロドのロバチェフスキー大学 （UNN） が、 oneAPI クロスアーキテクチャー ・プログラミングにより、 CPU、 GPU、 その他のアクセラレーターを利用して現代物理学の研究を促進する新たな oneAPI
研究拠点 （CoE） の開設を発表しました。 新しいセンターは、 ヘテロジニアス ・アーキテクチャー上でハイパフォーマンス ・ コンピューティング （HPC） を必要とする研究課題に取り組むとともに、 次世代の科学者を育成するためのソフトウェア ・ カリキュラムを拡充することを目的としています。
この記事の続きはこちら（英語）でご覧になれます。>

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

コードを賢くする

無料のインテル® パフォーマンス ・ライブラリーをダウンロードして、より優れた、 信頼性の高い、高速なアプリケーションを今すぐ作成しましょう。

無料のダウンロード （英語） >コンパイラーの最適化に関する詳細は、最適化に関する注意事項（software.intel.com/articles/optimization-notice#opt-jp）を参照してください。
Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国における Intel Corporation またはその子会社の商標です。
* その他の社名、製品名などは、一般に各社の表示、商標または登録商標です。
© Intel Corporation.

The Parallel Universe

29

GPU オフロードコードのメモリーとスレッドの正当性解析
インテル® Inspector でヘテロジニアス並列コードを簡単にデバッグ

Kevin O’ Leary インテル コーポレーション 主席テクニカル ・ コンサルティング ・ エンジニア
Michael Tutin インテル コーポレーション ソフトウェア ・ アーキテクト

現代のワークロードは多様であり、 アーキテクチャーも同様です。 すべてのワークロードに最適なアーキテクチャーはありません。 パフォーマンスを最大化するには、 CPU、 GPU、 FPGA、 およびその他のアクセラレーターにデプロイされる、 スカラー、 ベクトル、 行列、 および空間アーキテクチャーを組み合わせる必要があります。
複雑なヘテロジニアス環境では、 デバッグが困難になります。 この記事では、 アクセラレーターにオフロードする
コードの解析をサポートする、 インテル® Inspector の新機能を紹介します。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

30

インテル® Inspector の概要
適切なツールを使用しないでメモリーエラーや非決定的スレッドエラーを検出することは困難です。 インテル®
Inspector は、 これらのエラーを検出するように設計されています。 インテル® Inspector は、 Windows* やLinux* で実行する C、 C++、 DPC++、 および Fortran アプリケーション向けの、 動的なメモリーとスレッドのエラーのデバッガーです。

1

インテル® Inspector

図 1 は、 インテル® Inspector で検出できる問題の種類を示しています。
•• メモリーリーク、 無効なアクセス、 その他を含むメモリーエラー•• 不足しているか、 または冗長なキャッシュフラッシュなどのパーシステント ・ メモリー ・ エラー•• データ競合やデッドロックなどのスレッドエラー

インテル® Inspector は、 使いやすく、 信 頼 性 が 高く、 そして正 確 で す。 特 別な 再コンパイル は必 要 ありません。 通常の デバッグ またはプロダクション ・ ビルドを 使 用して、 エラーを検出してデバッグ できま す。
インテル® Inspector は、 ソースコードが利用できない場合でも、 動的に生成またはリンクされたコードを解析して、 サードパーティーのライブラリーを調べることができます。 問題が発生する直前に、 デバッガーにブレークインします。 コマンドライン ・ オプションを使用して、 リグレッション解析を自動化できます。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

31

インテル® Inspector を使用してオフロードコードを解析する方法
アクセラレーターにコードをオフロードすると、 正当性解析は複雑になります。 DPC++ の利用を進めるにつれて、オフロード問題のデバッグを支援するツールの必要性が明らかになりました。 インテル® Inspector の最新バージョンでは、 「早期インターセプト」 と呼ばれる重要な機能が追加されました。 この機能は、 カーネル実行前の初期段階でオフロードコードのいくつかの問題をインターセプトします。 表 1 と表 2 は、 インテル® Inspector を使用して検出できるオフロード問題のリストです。 共有データのデータ競合は、 レポートされますが次の制限があります。
•• DPC++ バリアと OpenMP* 同期は無視されます。 work-item が同期されている場合でも、 ツールは誤検出します。
•• カーネルのローカルメモリーで定義された変数のデータ競合は検出されません。
•• 次の手順は CPU でアプリケーションを実行するように設定しますが、 一部の GPU 解析は早期インターセプトを使用してサポートされています。

ステップ 1 は、 ホスト CPU で実行するようにアプリケーションを設定します。

次に、 カーネルを CPU デバイスで実行するように OpenMP* アプリケーションを設定します。

解析を実行する前にアプリケーションが正しく動作することを確認します。 JIT コンパイラー / ランタイムでコード
解析とトレースを有効にします。

インテル® Inspector 環境を設定します。

ステップ 2 は、 GUI （inspxe-gui） またはコマンドライン （inspxe-cl） を使用して、 小さなワークロードの解析を実行します。 コマンドラインで解析を実行する場合は、 次のコマンドを使用します。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

次のように結果を表示します。

GUI で結果を表示する場合は、 次のコマンドを使用します。

GUI で解析を実行して結果を表示することもできます （図 2 および図 3）。

2GUI で解析を実行するには、 プルダウンメニューから実行する解析を選択して ［Start （開始）］ ボタンをクリックします。 このスクリーンショットでは、 「Memory Error Analysis （メモリーエラー解析）」 を選択しています。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

32

The Parallel Universe3

デッドロックとデータ競合解析の結果をインテル® Inspector GUI で表示

使用例 ： デバイスでホストポインターを使用
次のコードにはメモリー問題が含まれています。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

33

The Parallel Universe

インテル® Inspector コマンドラインを使用してこのコードを解析し、 解析結果を GUI で表示します （図 4）。

4インテル® Inspector の解析結果。 コードのメモリーエラーの場所が示されています。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

34

The Parallel Universe

使用例 ： データ競合の検出
次のコードには競合状態が含まれています。

インテル® Inspector コマンドラインを使用してこのコードを解析し、 解析結果を GUI で表示します （図 5）。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

35

36

The Parallel Universe

5

インテル® Inspector の解析結果。 コードの書き込みデータ競合が示されている。

NEWS HIGHLIGHTS
イリノイ大学が NAMD に oneAPI クロスアーキテクチャー・プログラミング・
モデルを導入
イリノイ大学ベックマン先端科学技術研究所は、 ライフサイエンス ・アプリケーション NAMD に oneAPI
プログラミング ・ モデルを導入し、 新たなヘテロジニアス ・ コンピューティング 環境を追 加するため、
新しい oneAPI 研究拠点の設立を発表しました。 大規模な生体分子システムをシミュレーションする
NAMD は、 COVID-19 のような現実世界の課題に取り組むのに役立っています。
この記事の続きはこちら（英語）でご覧になれます。>

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

表 1. インテル® Inspector はさまざまなメモリー問題を検出

表 2. インテル® Inspector はデータ競合を検出

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

37

The Parallel Universe

38

まとめ
oneAPI は、CPU とアクセラレーターにデプロイされる、スカラー、ベクトル、行列、および空間アーキテクチャー
でシームレスに動作する、 標準の簡素化されたプログラミング ・ モデルを提供します。 oneAPI を利用することで、 ユーザーやドメイン ・ エキスパートは、 最適なマシン命令を生成するメカニズムではなく、 コードに集中することができます。 インテル® Inspector のような正当性解析ツールは、 検出が困難なスレッドやメモリー問題をデバッグする際に非常に役立ちます。

関連情報•• oneAPI （英語）•• インテル® oneAPI ツールキット•• インテル® Inspector

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

次の
レベルへ
導く
ライブラリーのツールを利用して優れたアプリケーションを簡単に開発できます。
関心のある分野、ツール、
ハードウェア別に選択可能です。

入手する （英語） >コンパイラーの最適化に関する詳細は、最適化に関する注意事項（software.intel.com/articles/optimization-notice#opt-jp）を参照してください。
Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国における Intel Corporation またはその子会社の商標です。
* その他の社名、製品名などは、一般に各社の表示、商標または登録商標です。
© Intel Corporation.

The Parallel Universe

40

インテル® コンパイラーの最適化
レポートを使用してチューニングの可能性を見つける
コード生成、 プロシージャー間の最適化、 浮動小数点精度など

Mayank Tiwari インテル コーポレーション クラウド ・ ソフトウェア ・ エンジニア
Rama Malladi インテル コーポレーション グラフィックス ・ パフォーマンス ・ エンジニア［訳者注 ： 記事内のコンパイラー ・ メッセージは、 日本語版のコンパイラーがインストールされている環境では
日本語で表示されます。］
インテル® C/C++ および Fortran コンパイラー ・ クラシックによって生成されるコンパイラー ・ レポートは、
コードの最適化に役立つ情報を提供します。 The Parallel Universe 41 号と 42 号では、 ループ変換とベクトル化のコンパイラー ・ レポートについて説明しました。 この記事では、 コード生成の最適化、 プロシー
ジャー間の最適化 （IPO）、 インライン展開、 データ ・ アライメント、 OpenMP* と自動並列化、 および浮動小数点精度のレポートについて説明します。 これらのレポートには、 コンパイラーによって生成されたコードの情報が示されており、 「最終的な」 コード変更と最適化を行うことでパフォーマンスを向上できます。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

41

最適化レポートの生成
インテル® C/C++ コンパイラー ・ クラシック では、 -qopt-report[=n] （Linux* および macOS*） または/Qopt-report[:n] （Windows*） オプションを指定すると、 コンパイラー ・ レポートが生成されます。 「n」
はオプションで、 レポートの詳細レベルを指定します。 0 （レポートを生成しない） から 5 （最も詳細なレポート）の値を指定できます。 この記事では、 -qopt-report=5 で生成されるレポート （最も詳細なレポート） について説明します。

コード生成
コンパイラー ・ レポート のコード生成 の 最 適 化セクションは、 利用可能なハードウェア ・ レジスター の 数、実際に使用された数、 およびスピルとフィルの回数の特定に役立ちます。 図 1 の単純な C++ ベクトル加算では、
図 2 に示すコンパイラーの最 適化レポートが生成されます。 入力引数、 グローバルおよびローカル変 数、
レジスタースピル、 およびスタックの使用に関連したレジスターの使用状況の詳細が分かります。

1

単純なベクトル加算の C++ コード

レジスターは CPU の ALU に最も近いメモリーであるため、レジスターの読み書きは高速です。 最高のパフォー
マンスを実現するには、 プログラマーはルーチン内の変数をレジスターに格納する必要があります。 しかし、レジスターの数には限りがあるため、コンパイラーはレジスター割り当てを最適化するコードを生成しようとします。
ルーチンが利用可能なレジスターよりも多くの変数を使用する場合、 一部の変数をスタックに退避して再び使用する際にロードする必要があります。 これはレジスタースピル / フィルと呼ばれます。 やむを得ない場合もありま
すが、 可能であれば、 ループ ・フィッションなどのループの最適化を適用することでレジスターの使用を最適化できます。 コンパイラーの最適化レポートで非常に多くのスピルが報告されている場合、 「高いレジスターのプレッシャー」 パフォーマンス問題を示しています。 その場合、 ループアンロールの回避、 ループ ・フィッションの使用、スカラーコードとベクトルコードの生成などにより、 レジスターのプレッシャーを最適化することが推奨されます。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

2

42

レジスターのプレッシャーとスタックの使用状況を示すインテル® C++ コンパイラーのコード生成レポート

プロシージャー間の最適化 （IPO）
図 3 の疑似コードは、 格子ボルツマン法 （LBM） アプリケーションから抜粋したものです。 図 4 と図 5 は、IPO が有効な場合と無効な場合のコンパイラーの最 適化レポートです。 コンパイル単位 lbm_file1.c とlbm_file2.c には、 関数 func_grids と func2 がそれぞれ含まれています。 func2 は、 タイムステップ ・
ループで func_grids を呼び出します。
コンパイラーのコード生成とパフォーマンスを向上させる最も一般的な最適化の 1 つは関数のインライン展開ですが、これは呼び出し先（関数定義）と呼び出し元（呼び出し）が単一のコンパイル単位にある場合にのみ実行できます。
図 3 の LBM の例には適用されません。 しかし、 インテル® コンパイラーでは、 プロシージャー間の最適化をサポートします （-ipo （Linux*） または /Qipo （Windows*） オプション）。 図 4 に示すように、 func_grids の呼び出しは、 func2 のループのベクトル化を妨げます。 IPO を使用すると、 コンパイラーはインライン展開することでこのようなループ / 関数呼び出しをベクトル化できるようになります （図 5）。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

3

コンパイラーによるプロシージャー間の最適化 （IPO） の適用を示すコード例

4

IPO が無効な場合の各ファイルに対するコンパイラーの最適化レポート

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

43

The Parallel Universe

5

44

IPO が有効な場合のコンパイラーの最適化レポート - インライン展開、 ベクトル化、 不要なスタティック関数の排除が行われたことを示しています。 1 つのレポート （ipo_out.optrpt） のみ生成されます。

関数のインライン展開
最も一般的なコンパイラーの最適化の 1 つは、 呼び出し先の関数を呼び出し元の中にインライン展開することです。
サイズが小さい関数ほど、 インライン展開される可能性が高くなります。 コンパイラーは一般にインライン展開による 「コードの膨張」 を制限しようとしますが、 図 6 に示すオプションを変更することで、 コンパイラーの保守的な判断を変更できます。

6

インライン展開に関連したコンパイラー ・ オプション

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

45

浮動小数点モデルと精度
科学アプリケーションでは、 一般に高い計算精度を維持することが求められることがあります。 これは、 32 ビットの代わりに 64 ビットの浮動小数点データ型を使用することで達成できます。 しかし、 可能な場合には、 より低い精度のデータ型を使用すると、 パフォーマンスが向上します。 さらに、 -fp-model precise （Linux*） または
fp:precise （Windows*） オプションを使用して、 数値再現性 / 一貫性に影響するコンパイラーの最適化を無効にすることができます。
図 7 のコードは、 2 次元配列の 2 乗ノルムを計算します。 このコードを precise 浮動小数点モデルでコンパイルすると、 コンパイラーは内部ループをベクトル化できません （図 8）。 より低い精度の浮動小数点モデル（デフォルト） では、 レポートで提案されているように、 コンパイラーはより積極的な最適化を行うことができます。

7

単純な 2 レベルのリダクション ・ ループ

8precise 浮動小数点モデルは最適化を制限

OpenMP* と自動並列化
現代のプロセッサーにおけるもう 1 つの高速化の 機会は並列化です。 インテル® コンパイラーは、 安全に並列化できると判断した場合 （自動並列化）、 または OpenMP* を使用して明示的に並列化されている場合、並列化をサポートします （図 9）。 コンパイラーの最適化レポートは、OpenMP* （-qopenmp （Linux*） または/Qopenmp （Windows*）） と自動並列化 （-parallel （Linux*） または /Qpar （Windows*）） オプションが使用されると、 並列化されたループを報告します （図 10）。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

9

OpenMP* の並列構文とコンパイラーにより自動並列化される可能性がある領域を含むコード

10

OpenMP* と自動並列化に関するコンパイラー ・ レポート

46

まとめ
インテル® コンパイラーは、 豊富な機能セット、 パフォーマンスの最適化、 最新の言語標準のサポートを提供します。
ぜひ、 最新のコンパイラーでいくつかのコンパイラー ・ オプションを変更して、 アプリケーション ・ パフォーマンスの向上を体験してください。 この記事および以前の記事で説明したコンパイラー ・ レポートは、 コンパイラーの振る舞いを理解するのに役立ちます。 これらの記事で紹介した例は、 重要なポイントの理解を助けます。

関連情報
1. インテル® 64 および IA-32 アーキテクチャー ・ ソフトウェア開発者マニュアル （英語）
2. インテル® C++ コンパイラー ・ クラシック ・ デベロッパー ・ ガイドおよびリファレンス （英語）
3. インテル® コンパイラーの浮動小数点演算における結果の一貫性

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

将来に向けた取り組み
技術的なスキルアップ、
エキスパートからの回答、新しい開発分野への挑戦。
これらすべてにインテルの無料の技術ウェビナー（オンデマンド）が役立ちます。

トピックを選択 （英語） >コンパイラーの最適化に関する詳細は、最適化に関する注意事項（software.intel.com/articles/optimization-notice#opt-jp）を参照してください。
Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国における Intel Corporation またはその子会社の商標です。
* その他の社名、製品名などは、一般に各社の表示、商標または登録商標です。
© Intel Corporation.

The Parallel Universe

48

インテル® MPI ライブラリーを使用したクラスター全体の
MPI チューニング
mpitune_fast ユーティリティーを使用した MPI 集合通信のチューニング

Amarpal S Kapoor 博士 インテル コーポレーション テクニカル ・ コンサルティング ・ エンジニア
Marat Shamshetdinov インテル コーポレーション ソフトウェア開発エンジニア

この 記 事は、 インテル® MPI ライブラリー （英 語） の チューニング ・ ユーティリティーに関 するシリーズの続編です。 以前の記事では、 主にアプリケーション固有のチューニング ・ ツールと手法を取り上げましたが、この記事では mpitune_fast ユーティリティーを使用したクラスター全体のチューニングに注目します。 理想的には、 ユーザーが最適にチューニングされたインテル® MPI ライブラリーを利用できるように、 クラスター管理者がmpitune_fast を実行すべきです。 しかし、mpitune_fast は、非特権ユーザーによっていつでも実行できます。
この記事では、 mpitune_fast を紹介し、 インテル® MPI Benchmarks （IMB） （英語） のチューニング手法とそれによって得られるパフォーマンス ・ ゲインを説明します。 この記事内のすべての検証には、 インテル® MPI
ライブラリー 2019 Update 9 と、 インテル® Xeon® プロセッサー ・ ベースの クラスター Endeavor （英語）およびインテル® DevCloud （英語） が使用されています。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

49

Autotuner （英語） の 使いやす さ、 低 オーバーヘッド、 そして潜在的なパフォーマンス向上に触 発されて、インテル® MPI ライブラリーの開発チームは、 個別のアプリケーションだけでなく、 クラスター全体にチューニング
の範囲を拡大しました。 ほとんどの MPI アプリケーションに適用できるチューニング ・ データを生成する IMB と
Autotuner を組み合わせることで、 クラスター全体のチューニング ・ユーティリティー mpitune_fast が誕生しました （図 1）。

1

mpitune_fast のコンポーネント

mpitune_fast は、 事前に定義された設定で IMB を繰り返し実行して、 インテル® MPI ライブラリーのデフォ
ルト設定よりも優れたクラスター固有のチューニング ・ パラメーターを検証します。 生成された設定はファイルに保存され、 クラスター上で実行されているすべての MPI アプリケーションで利用できます。 クラスター管理者は、
クラスター上で実行されているすべての MPI アプリケーションが mpitune_fast の解析結果を利用できるよ
うに、 I_MPI_TUNING_BIN 環境変数にこのファイルへのパスを設定できます。

mpitune_fast の主な機能
クラスター全体のチューニング
クラスター全体のチューニングは、 2 つのステップで構成されます。
1. クラスター上で実行されているすべてのアプリケーションで有効なチューニング ・ データの生成
2. 複数のノード （1 から Nmax） とノードごとのプロセス （1 から Cmax） を組み合わせたチューニング設定の生成

クラスターの設定に変更がない限り、 mpitune_fast は一度実行するだけで済みます。

動的なチューニング
Autotuner ベースの mpitune_fast は、 動的なチューニング機能を継承しており、 チューニング全体のオーバーヘッドを大幅に軽減し、 ユーザー ・ ワークフローを簡素化します。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

50

並列チューニング
mpitune_fast はクラスター全体のチューニング ・ ツールであるため、 複数の MPI ランク配置スキームと可変ノード数に応じてチューニングすることが重要です。 これは、可能な限り、複数のノードあたりのプロセス数（-ppn）とノードの総数 （-n） に対して並列にチューニングすることで達成されます。 大きな -ppn （ノードあたりの物
理コア数に近い） と -n （hostfile 内のノード総数に近い） 値をチューニングする場合、 チューニングの実行は本質的にシリアルになります。 しかし、 小さな -ppn と -n 値の場合、 mpitune_fast はハードウェアを活用してチューニング全体のオーバーヘッドを軽減するため、自動的に並列チューニング・インスタンスを起動します。

使いやすさ
mpitune_fast の設計目標は、 シンプルなユーザー ・ ワークフローと呼び出しスキームを維持することです。
そのため、IMB と Autotuner の実行に関連した複雑性はユーザーから隠蔽されています。 mpitune_fast は、
ランタイムオプションと環境変数を介して、 ツールを慎重に設定します。

手法
mpitune_fast の使い方はとても簡単です。 次のコマンドは、 LSF または Slurm ジョブ ・スケジューラーを実行している （hostfile の自動検出が有効な） クラスター上で mpitune_fast を起動します。

ほかのジョブ ・ スケジューラーを実行しているクラスター上では、 追加で mpitune_fast を実行するノードのリストを含むファイルを指定する必要があります。

mpitune_fast にはわずかな引数があるだけです。 次のヘルプオプションを使用して確認できます。

デフォルトでは、 mpitune_fast は複数のノードあたりのプロセス数 （-ppn） とノード数 （-n） （つまり、 最大
で -ppn の物理コア数を含む物理コア数までのすべての 2 のべき乗と最大でホスト数までのすべての 2 のべき乗）向けにチューニングします。 例えば、 50 ノード、 ノードあたり 24 物理コアのクラスターの場合、 デフォルトでは
mpitune_fast は、 -n 値 1、 2、 4、 8、 16、 32、 50 と -ppn 値 1、 2、 4、 8、 16、 24 をテストします。 クラス
ター上のジョブによる -n と -ppn の一般的な使用パターンが判明している場合、カンマ区切りのリストを使用して、-ppn 値と -n 値を 1 つ以上の値に制限できます （または、 カスタム値の指定も可能です）。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

51

さらに、 -c オプションを使用してチューニング対象の範囲を制限することで、 チューニング ・ オーバーヘッドを軽減できます （デフォルトでは、 allreduce、 reduce、 bcast、 および barrier がチューニング対象となります）。

これらのコマンドを実行すると、 チューニング ・ファイルが生成されます。 これは、 このクラスター上で実行しているすべての MPI アプリケーション用のデフォルトのチューニング ・ファイルとして使用できます。 mpitune_fast
で -n オプションを使用する場合は注意が必要です。 ここではノード数を表しますが、 mpirun や mpiexec.
hydra では、 -n はランクの総数を表します。 mpitune_fast では、 ユーザー指定のディレクトリーにチューニ
ング結果を保存する -d オプションも利用できます。
mpitune_fast のパフォーマンスを評価するため、 IMB を使用して一般的な MPI 集合通信関数 Allreduce、
Bcast、 Reduce、 Scatter、 および Gather のパフォーマンスを測定します。 テストスクリプトは、 3 つのステップを実行します。
最初に、 次のコマンドを使用して、 インテル® MPI ライブラリーのデフォルトのチューニング設定で IMB を実行します。

表 1 に、 このコマンドで使用した変数の値を示します。
表 1. テスト設定

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

52

IMB でメッセージサイズごとに実行する繰り返し回数を厳密に制御するため、 単一のコマンドで 1B から 4MB のメッセージ範囲全体のパフォーマンスをテストする代わりに、 3 つの実行に分割します。 そして、 3 つの実行で-iter と -msglog の引数を変更します （表 2）。
表 2. メッセージサイズに応じた繰り返し回数を選択

表 2 に示すように、 サイズが 21B から 216B の小規模なメッセージでは繰り返し回数を 1,000 回とし、 217B から219B の中規模のメッセージでは 600 回とし、 220B から 222 B の大規模なメッセージでは 20 回とします。
このステップで収集されたパフォーマンス ・ データが、 ベースライン ・ パフォーマンスになります。 IMB のメッセージ
サイズあたりの t_max メトリックは、 集合呼び出しのすべてのランクにおいて最もパフォーマンスが悪く、 安全な
パフォーマンス指標であるため、 これを追跡します。
次に、 mpitune_fast を非特権ユーザーで実行します （この記事は、 クラスター管理者だけでなく、 すべてのクラスターユーザーを対象としているため、 ここではあえて非特権ユーザーで実行します）。

ここでは、 ノード数、 ノードあたりのプロセス数、 注目する MPI 関数を指定してチューニングを制限しています。
上記のコマンドを実行すると、 チューニング済みの設定を含むバイナリーファイルが生成されます。
最 後に、 チューニング ・ ファイル を 使 用して mpitune_fast 解 析 の 利点を 評 価しま す。 次の 環 境 変 数 でインテル® MPI ライブラリーが使用するチューニング ・ファイルを指定します。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

53

結果
このセクションでは、 前述のステップを 2 つのインテル® Xeon® プロセッサー ・ ベースのクラスター Endeavour とインテル® DevCloud で実行して収集したデータを示します。 Endeavour では、 Mellanox* Quantum* HDR
インターコネクトで接続された 16 個のインテル® Xeon® Platinum 8268 プロセッサー ・ ベースのデュアルソケット・ノードを使用しました。 インテル® DevCloud では、 イーサネット・インターコネクトで接続された 8 個のインテル® Xeon® Gold 6128 プロセッサー ・ ベースのデュアルソケット ・ノードを使用しました。

2

Endeavour での 5 つの一般的な MPI 集合通信関数のパフォーマンス向上

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

3

54

インテル® DevCloud での 5 つの一般的な MPI 集合通信関数のパフォーマンス向上

図 2 は、 Endeavour 上で観測されたパフォーマンスの向上です。 メッセージサイズ範囲全体ですべての関数のパフォーマンスが平均 11.15% 向上しました。 図 2 の 111 個のデータポイント中、 5 個のデータポイント
でパフォーマンスの低下が見られました。 mpitune_fast 開発チームは、 これを改善するためチューニング
手法の調整に取り組んでいます。 また、 このようなわずかな低下は、 同じスイッチに接続されたノード上で実行されている別のアプリケーションからのノイズやネットワーク ・ トラフィックに起因する可能性があります。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe55

図 3 は、 インテル® DevCloud 上で観測されたパフォーマンスの向上です。 メッセージサイズ範囲全体ですべての関数のパフォーマンスが平均 36.35% 向上しました。 Endeavour とは異なり、 パフォーマンスの低下は見られませんでした。

制限事項
2019 Update 9 バージョンの mpitune_fast には、 次の制限があります。
1. 非ブロッキング集合は未サポートです。
2. 設 計上、 mpitune_fast は 現 在、 IMB に よる チューニング ・ デ ー タの 生 成 の み を サ ポ ートして い ま す。
ユーザー指定のベンチマーク ・ アプリケーションに基づくチューニングはサポートされていません。
3. ユーザー定義のメッセージサイズ固有の条件付きチューニングは現在利用できません。

まとめ
この記事では、 インテル® MPI ライブラリーのチューニング ・ ユーティリティーの 1 つである mpitune_fast
を使用して、 クラスター全体のチューニング ・ データを生成する便利な方法を紹介しました。 このユーティリ
ティーは、 クラスター管理者と非特権ユーザーの両方が実行できます。 Endeavour とインテル® DevCloud
上では、 5 つの一般的な MPI 関数のパフォーマンスが平均でそれぞれ 11.15% と 36.35% 向上しました。
mpitune_fast で生成したチューニング ・ データは任意のアプリケーションに適用できる一方、 Autotuner は
アプリケーション固有のチューニング ・ データを生成できるため、 アプリケーションに追加のパフォーマンス向上
を提供します。 推 奨 さ れるワ ー ク フローは、 最 初 にクラス ター 管 理 者 が mpitune_fast を 実 行してクラスター向けのインテル® MPI ライブラリーの最適なチューニング設定を生成した後、 クラスターユーザー
が Autotuner を実行してアプリケーション固有の設定を生成することです。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

56

マシンラーニング向け線形モデルの高速化
線形回帰がこれまでになく高速にVictoriya Fedotova インテル コーポレーション マシンラーニング・エンジニア

Python* と scikit-learn を使用して大規模なデータセットからマシンラーニング （ML） モデルを構築した経験がある場合、 これらの計算を高速化したいと思われたことがあるかもしれません。 1 行のコードを変更するだけでML の計算を高速化できるとしたらどうしますか ? また、 特別なハードウェアなしでより高速な結果が得られるとしたらどうでしょう ?

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

57

この記事では、 インテル® CPU 向けに最適化された scikit-learn （英語） を使用してリッジ回帰モデルをトレーニングする方法を紹介し、 標準の scikit-learn ライブラリーでトレーニングしたモデルのパフォーマンスおよび精度と比較します。 この記事は、 高速な ML アルゴリズム ・ シリーズの 1 つです。
•• インテル® Xeon® プロセッサー向け勾配ブースティング木推論の高速化 （英語）•• 第 2 世代インテル® Xeon® スケーラブル ・ プロセッサーで K 平均法を高速化 （英語）

線形回帰の実践例
特殊なリッジ回帰である線形回帰にはさまざまな用途があります。 ここでは、 良く知られている Kaggle （英語）の House Sales in King County, USA （米国キング郡の住宅販売） （英語） データセットを使用して、 キング
郡の 1 年間の住宅販売データを基に住宅価格を予測してみます。
このデータセットには、 21,613 行と 21 列があります。 各行は、 2014 年 5 月から 2015 年 5 月までにキング
郡で販売された住宅を表します。 第 1 列には販売を識別する一意の ID、 第 2 列には住宅の販売日、 そして第 3
列には販売価格 （ターゲット変数） が含まれています。 第 4 列から第 21 列には、 寝室数、 広さ、 築年数、
郵便番号など、 住宅に関するさまざまな数値的特徴が含まれています。 これらの情報を基に、 住宅の販売価格を予測するリッジ回帰モデルを構築します。
理論的には、 線形回帰モデルの係数は最小残差平方和 （RSS） にすべきです。 実際には、 最小 RSS のモデルが必ずしも最良であるとは限りません。 線形回帰は、 入力データが多重共線性を持つ場合、 不正確なモデルを生成することがあります。 この場合、 リッジ回帰はより信頼性の高い予測を提供できます。

scikit-learn で回帰問題を解く
sklearn.linear_model.Ridge でモデルを構築する方法を説明します。 次のプログラムは、住宅販売デー
タセットの 80% の行でトレーニングを行い、 残り 20% の行でモデルの精度をテストします。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

58

The Parallel Universe

59

R2 は 0.69 になりました。 つまり、 構築したモデルはデータ分散の 69% を表しています。 トレーニング済みモデ
ルの品質に関する詳細は、 「付録」 を参照してください。

インテルにより最適化された scikit-learn
リッジ回帰によるトレーニングと予測時間は非常に高速ですが、 ハイパーパラメーターをチューニングするため、通常、 トレーニングを複数回実行する必要があります。 また、 予測精度を向上させるため、 さまざまな特徴のサブセットでモデルを評価してみるとよいでしょう。 大規模なデータセットでは 1 回のトレーニングに数分かかることもあり、 トレーニングを複数回実行するには長時間を要するため、 線形モデルのトレーニングのパフォー
マンスは重要です。
Python* 向けインテル® ディストリビューションは、 ネイティブ Python* のドロップイン置換であり、 インテル®
アーキテクチャー向けに最適化されています。 conda や pip などの一般的なチャネルからインストール可能なパッケージとシームレスに動作します。 Python* 向けインテル® ディストリビューションの scikit-learn には、Continuum の scikit-learn と同じアルゴリズムと API のセットが含まれているため、 ML アルゴリズムのパフォーマンスを向上するためコードを変更する必要はありません。
また、 daal4py （インテル® oneAPI データ ・ アナリティクス ・ ライブラリー （インテル® oneDAL） （英語） のPython* インターフェイス） を利用することで、 scikit-learn のパフォーマンスをさらに向上することが可能です。
daal4py は、 構成可能な ML カーネルを提供し、 その一部はストリーミング入力データをサポートしており、
ワークステーションのクラスターに容易にスケーリングできます。

scikit-learn と daal4py の設定方法
Python* 向けインテル® ディストリビューションをインストールする方法はいくつかあります。 conda でインストール
するには、 こちらの手順に従ってください。
次のコマンドは、 'idp' conda 環境に daal4py をインストールします。

ソルバーとして daal4py を使用するには、 scikit-learn の動的なパッチを適用する必要がありますが、 アプリケー
ションを変更することなくパッチを有効にできます。 次のコマンドライン ・ オプションを使用します。

アプリケーション内でパッチを有効にすることもできます。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

60

パッチを元に戻すには、 次のコマンドを実行します。

パッチを適用すると、 次の scikit-learn アルゴリズムに影響します。
•• sklearn.linear_model.LinearRegression （英語）•• sklearn.linear_model.Ridge （solver='auto'） （英語）•• sklearn.linear_model.LogisticRegression （ 英 語 ） と sklearn.linear_model.LogisticRegressionCV（['lbfgs', 'newton-cg'] のソルバー） （英語）•• sklearn.decomposition.PCA （svd_solver='full'、 および svd_solver='daal' の追加） （英語）•• sklearn.cluster.KMeans （algo='full'） （英語）•• sklearn.metric.pairwise_distance （metric='cosine' または metric='correlation'） （英語）•• sklearn.svm.SVC （英語）

このリストは、 Python* 向けインテル® ディストリビューションの次のリリースで拡張される予定です。

パフォーマンスの比較
標準の scikit-learn とインテルにより最適化された scikit-learn のパフォーマンスを比較するため、 キング郡の
データセットに加えて、 サンプル数と特徴量が異なる 6 つの人工的に生成されたデータセットを使用しました。
人工的なデータセットは、 make_regression 関数を使用して生成しました。

図 1 は、 次の 2 つの構成でリッジ回帰モデルのトレーニングにかかった実時間です。
•• デフォルトの conda チャネルからインストールした scikit-learn 0.22•• daal4py で最適化された Python* 向けインテル® ディストリビューションの scikit-learn 0.21.3

インテル® oneDAL の scikit-learn 最適化を有効にするため、 -m daal4py コマンドライン ・ オプションを使用しました。 パフォーマンスの測定には、 Amazon Web Services* Elastic Compute Cloud* （AWS* EC2*） を使用し、 最高のパフォーマンスを提供する次のインスタンスを選択しました。
•• CPU ： c5.metal （第 2 世代インテル® Xeon® スケーラブル ・プロセッサー、 2 ソケット、 ソケットごとに 24 コア）。

Amazon は次のように述べています。
「C5 インスタンスは、 コンピューティング集約型ワークロードのために最適化されており、 低いコンピューティング
あたりの価格率でコスト効率が高い優れたパフォーマンスを実現します。」
c5.metal インスタンスは、 C5 インスタンスの中で最も多くの CPU コア数と最も新しい CPU を搭載しています。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

161

リッジ回帰のトレーニング時間

ハードウェアの詳細は、 「システム構成」 セクションを参照してください。 トレーニング済みモデルの品質に関する
詳細は、 「付録」 を参照してください。
図 1 から、 次のことが分かります。
•• インテルにより最適化された scikit-learn は、 標準の scikit-learn と比較して、 リッジ回帰のトレーニングが最大 5.49 倍高速です。
•• デ ー タ セット の サイズ に 応じ て、 イ ン テル に より 最 適 化 さ れ た scikit-learn のパ フォ ーマ ンス の 向上は大きくなります。

Python* 向けインテル® ディストリビューションの scikit-learn が高速な理由
大規模なデータセットでは、 リッジ回帰はほとんどの計算時間を行列乗算に費やします。 インテル® oneDALのリッジ回帰実装は、 インテル® CPU 向けに高度に最適化されたインテル® マス ・ カーネル ・ ライブラリー（インテル® MKL） を利用しています。 インテル® MKL は、 第 2 世代インテル® Xeon® スケーラブル ・プロセッ
サーで利用可能なインテル® アドバンスト ・ ベクトル ・ エクステンション 512 （インテル® AVX-512） の SIMD（Single Instruction Multiple Data） ベクトル命 令を 使 用します。 行列乗算な どの 計算集 約型 カーネルは、
これらの命令によるデータ並列性から大きな恩恵を受けます。 さらに、 行列をブロック分割してインテル® スレッ
ディング ・ ビルディング ・ブロック （インテル® TBB） で並列に処理することで、 行列乗算において別のレベルの並列性が得られます。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

62

インテルにより最適化された scikit-learn は、 モデルの精度を損なわず、 わずかなコード変更でリッジ回帰のパフォーマンスを大幅に向上します。 パフォーマンスの優位性は、 このアルゴリズムに限ったことではありません。
前述のように、 最適化された ML アルゴリズムのリストは拡張し続けています。

システム構成ハードウェアc5.metal AWS* EC2* インスタンス ： インテル® Xeon® Platinum 8275CL プロセッサー、 2 ソケット、 ソケット
ごとに 24 コア、 192GB RAM。 OS ： Ubuntu* 18.04.3 LTS.

ソフトウェア
通常の sklearn ： Python* 3.8.0、 scikit-learn 0.22、 pandas 0.25.3。
Python* 向けインテル® ディストリビューションの scikit-learn ： インテルのチャネルからの conda インストール ：Python* 3.7.4、 scikit-learn 0.21.3 （daal4py 2020.0 build py37ha68da19_8 で最適化）、 pandas 0.25.1。
Python* およびライブラリーは、 それぞれの環境を構成するときに conda パッケージ ・ マネージャーによりインストールされるデフォルトバージョン。

付録
表 1 リッジ回帰モデルの平均二乗偏差 （RMSD） と決定係数 （R²）

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

インテル® DevCloud
デ ー タ センターか ら エッジ ま で広 範 な
ワークロードに対応した開発サンドボックス
最新のインテル製ハードウェアとソフトウェアを搭載したクラスター上でワークロードを開発、 テスト、 実行

統合されたインテルの最適化フレームワーク、 ツール、 ライブラリーを利用することで、 プロジェクトに必要なものがすべて揃います。

インテルのさまざまなハードウェアを評価

自然言 語 処 理 や 時 系列 解 析 な どの 機 能 を 備 え た 最 先 端 の クラスターと、 エッジ ・ アクセラレ ーション ・ ハードウェアを利用して、スキルを高め、 さまざまな実験を行うことができます。

インテル® ソフトウェア開発ツールで開発

インテルから最新のコンパイラー、 パフォーマンス ・ ライブラリー、
ツールをダウンロード、 設定、 およびインストールせずに、 すぐに
プロジェクトを開始できます。

ポピュラーな AI フレームワークを使用

トレ ーニングと 推 論 をすぐに開 始で きるインテル® Optimized AI
Frameworks を利用してアルゴリズムとアプリケーションを高速化できます。

今すぐ開始 （英語） >コンパイラーの最適化に関する詳細は、最適化に関する注意事項（software.intel.com/articles/optimization-notice#opt-jp）を参照してください。
Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国における Intel Corporation またはその子会社の商標です。
© Intel Corporation

The Parallel Universe

64

XGBoost と LightGBM
推論パフォーマンスの向上
インテル® oneAPI データ ・アナリティクス ・ ライブラリーにより推論を最大 36 倍高速化

Igor Rukhovich インテル コーポレーション マシンラーニング ・ インターン

決定木に対する勾配ブースティングは、最も正確で効率良い分類と回帰のマシンラーニング・アルゴリズムの 1 つです。
多くの勾配ブースティング実装がありますが、 最も一般的なのは XGBoost （英語） と LightGBM （英語） フレームワークです。 この記事では、 インテル® oneAPI データ ・アナリティクス ・ ライブラリー （インテル® oneDAL） （英語）を使用して XGBoost と LightGBM モデルの推論スピードを最大 36 倍向上する方法を紹介します。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

65

勾配ブースティング
XGBoost と LightGBM 勾配ブースティングは、 実際の問題、 研究、 Kaggle （英語） コンペティション で幅広く利用されています。 これらのフレームワークは、 デフォルトの設定でも優れたパフォーマンスを提供しますが、推論スピードには向上の余地があります。 推論はマシンラーニング ・ ワークフローの最も重要なステージであることを考慮すると、 パフォーマンス向上によってもたらされる利点は少なくありません。

以前の記事 「勾配ブースティング木推論の高速化」 （英語） では、 インテル® oneDAL が他の製品と比較して勾配ブースティング推論を数倍高速に実行できることが示されました。 このパフォーマンスの利点を XGBoost とLightGBM でも利用できるようになりました。

モデル ・ コンバーター
すべ ての勾配ブースティング実装は、 同様の 処 理を実行するため、 同様のデータストレージを 使用します。
理論的には、 これはあるマシンラーニング ・フレームワークから別のマシンラーニング ・フレームワークへのトレー
ニング済みモデルの変換を容易にします。 インテル® oneDAL のモデル ・コンバーターは、 たった 1 行のコードでトレーニング済みモデルを XGBoost や LightGBM からインテル® oneDAL へ移行できるように設計されています。
ほかのフレームワーク向けのモデル ・コンバーターも今後リリースされる予定です。
次の例は、XGBoost と LightGBM モデルをインテル® oneDAL へ変換する方法を示します。 最初に、Python* 3.6
以降向けの最新の daal4py （英語） を入手します。

XGBoost モデルからインテル® oneDAL への変換 :コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe

66

LightGBM モデルからインテル® oneDAL への変換 :トレーニングと推論での欠損値 （NaN） には、 一時的な制限があることに注意してください。 データに欠損値が含まれる場合、 推論の品質が低下する場合があります。
次の例は、 インテル® oneDAL にモデルを保存してロードする方法を示します。

デフォルトでは、 インテル® oneDAL は予測された要素のラベルのみを返します。 確率も必要な場合は、 明示的に要求する必要があります。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe67

パフォーマンスの比較
次の既製のデータセットを使用して、 XGBoost や LightGBM と比較したインテル® oneDAL のパフォーマンスの利点を検証できます。
•• Mortgage （英語） ： 特徴 45、 観測約 9M•• Airline （英語） ： 特徴 691 、 one-hot エンコーディング、 観測約 1M•• Higgs （英語） ： 特徴 28、 観測約 1M•• MSRank （英語） ： 特徴 136、 観測 3M

モ デル は XGBoost と LightGBM でトレ ーニ ング して か ら、 daal4py へ 変 換 し ま し た。 XGBoost お よ びLightGBM と daal4py のパフォーマンスを比較するため、 オリジナルのモデルと変換したモデルの推論時間を測定しました。 図 1 から、 daal4py は XGBoost よりも最大 36 倍 （平均 24 倍） 高速であり、 LightGBM よりも
最大 15.5 倍 （平均 14.5 倍） 高速であることが分かります。 推論品質は同じままです （回帰では平均 2 乗誤差、分類では精度とロジスティック損失で測定）。
インテル® oneDAL は、 インテル® アドバンスト ・ ベクトル ・ エクステンション 512 （インテル® AVX-512） 命令セットを使用して、 インテル® Xeon® プロセッサー上で勾配ブースティング ・ パフォーマンスを最大化します。 比較やランダム ・ メモリー ・アクセスなどのよく使用される推論操作は、 インテル® AVX-512 の vpgatherd{d,q} および
vcmpp{s,d} 命令を使用して効率良く実装できます。 パフォーマンスは、 ストレージ効率やメモリー帯域幅にも依存します。 木構造の場合、 インテル® oneDAL は、 メモリー内のデータをスマートにロックすることで、 一時的にキャッシュを局在化して （つまり、 木のサブセットと観測ブロックが L1 データキャッシュに格納されている状態にして）、 メモリーアクセスの大部分が最も高いメモリー帯域幅を持つ L1 レベルでヒットするようにします。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

The Parallel Universe1

daal4py と LightGBM （上） および XGBoost （下） の推論パフォーマンスの比較 （ハードウェアとソフトウェアの構成は、 本記事の最後に記載されています）

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

68

The Parallel Universe

69

まとめ
多 く のア プ リ ケーション が勾 配ブース ティング に XGBoost と LightGBM を 使 用して い るた め、 モ デル ・コンバーターはインテル® oneDAL を使用して推論を高速化する簡単な方法を提供しています。 XGBoost とLightGBM のユーザーは、 次の利点が得られます。
•• 変更なしで既存のモデル ・ トレーニング ・ コードを使用できます。
•• 最小のコード変更で品質を低下されることなく推論を最大 36 倍高速化できます。

ハードウェアとソフトウェアの構成
イ ン テル® Xeon® Platinum 8275CL プ ロ セ ッ サー （第 2 世代イ ン テル® Xeon® ス ケーラブル ・ プ ロ セ ッサー） ： 2 ソケット、 ソケットごとに 24 コア、 ハイパースレッディング ・ テクノロジー有効、 インテル® ターボ ・
ブースト ・ テクノロジー有効。 OS ： Ubuntu* 18.04.4 LTS （Bionic Beaver）、 合計メモリー 192GB （12 スロット /16GB/2933MHz）。 ソフトウェア ： XGBoost 1.2.1、 LightGBM 3.0.0、 daal4py バージョン 2020 Update 3、Python* 3.7.9、 NumPy* 1.19.2、 pandas 1.1.3、 scikit-learn 0.23.2。 トレーニング・パラメーター：XGBoost （英語）および LightGBM （英語）。

コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

intel®software

THE PARALLEL

UNIVERSE

インテルのテクノロジーを使用するには、 対応したハードウェア、 ソフトウェア、 またはサービスの有効化が必要となる場合があります。 詳細については、 OEM または販売店にお問い合わせいただくか、
http://www.intel.co.jp/ を参照してください。
実際の費用と結果は異なる場合があります。
インテルは、 サードパーティーのデータについて管理や監査を行っていません。 ほかの情報も参考にして、 正確かどうかを評価してください。
最適化に関する注意事項 ： インテル® コンパイラーでは、 インテル® マイクロプロセッサーに限定されない最適化に関して、 他社製マイクロプロセッサー用に同等の最適化を行えないことがあります。
これには、 インテル® ストリーミング SIMD 拡張命令 2、 インテル® ストリーミング SIMD 拡張命令 3、 インテル® ストリーミング SIMD 拡張命令 3 補足命令などの最適化が該当します。 インテルは、他社製マイクロプロセッサーに関して、 いかなる最適化の利用、 機能、 または効果も保証いたしません。 本製品のマイクロプロセッサー依存の最適化は、 インテル® マイクロプロセッサーでの使用を前提としています。 インテル® マイクロアーキテクチャーに限定されない最適化のなかにも、 インテル® マイクロプロセッサー用のものがあります。 この注意事項で言及した命令セットの詳細については、該当する製品のユーザー ・ リファレンス ・ ガイドを参照してください。 注意事項の改訂 #20110804。
https://software.intel.com/articles/optimization-notice#opt-jp
性能に関するテストに使用されるソフトウェアとワークロードは、 性能がインテル® マイクロプロセッサー用に最適化されていることがあります。   
SYSmark* や MobileMark* などの性能テストは、 特定のコンピューター ・ システム、 コンポーネント、 ソフトウェア、 操作、 機能に基づいて行ったものです。 結果はこれらの要因によって異なります。
製品の購入を検討される場合は、 他の製品と組み合わせた場合の本製品の性能など、 ほかの情報や性能テストも参考にして、 パフォーマンスを総合的に評価することをお勧めします。 性能やベンチマーク
結果について、 さらに詳しい情報をお知りになりたい場合は、 http://www.intel.com/benchmarks/ （英語） を参照してください。
性能の測定結果はシステム構成の日付時点のテストに基づいています。 また、 現在公開中のすべてのセキュリティー ・ アップデートが適用されているとは限りません。 詳細は、 システム構成を参照してください。 絶対的なセキュリティーを提供できる製品またはコンポーネントはありません。
本資料は、 （明示されているか否かにかかわらず、 また禁反言によるとよらずにかかわらず） いかなる知的財産権のライセンスも許諾するものではありません。
インテルは、 明示されているか否かにかかわらず、 いかなる保証もいたしません。 ここにいう保証には、 商品適格性、 特定目的への適合性、 および非侵害性の黙示の保証、 ならびに履行の過程、取引の過程、 または取引での使用から生じるあらゆる保証を含みますが、 これらに限定されるわけではありません。
© Intel Corporation. Intel、 インテル、 Intel ロゴ、 Xeon は、 アメリカ合衆国および / またはその他の国における Intel Corporation またはその子会社の商標です。
* その他の社名、 製品名などは、 一般に各社の表示、 商標または登録商標です。
JPN/2102/PDF/XL/SPI/ND