インテル® System Studio による自動運転のチューニング
Julia: スーパーコンピューティング向け高水準言語
ベクトル化が再び重要に

00001101
00001010
00001101
00001010
01001100
01101111
01110010
Issue
01100101
01101101
00100000
2017
01101000
01110001
01110011
0111010129

目次
編集者からのメッセージ
C90 と Julia

2

3

注目記事

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

インテル® System Studio による自動運転のチューニング
インテル® GO™ 車載機器用ソフトウェア開発キットが提供する車載機器用ソリューション開発者向け
統合ソリューション環境

OpenMP* 20 周年
並列プログラミングを C/C++ および Fortran プログラマーが利用しやすいものに

Julia: スーパーコンピューティング向け高水準言語

5

19

23

科学計算の新しい壁を乗り越える Julia プロジェクト

ベクトル化が再び重要に
オープンソース ・ コード WARP3D がベクトル化に新たな関心が寄せられていることを実証

クラウドおよびエッジ ・アプリケーション向けの高速データ圧縮コードのビルド
インテル® IPP を利用した圧縮の最適化

インテル® C++ コンパイラーによる MySQL* の最適化
LeCloud の MySQL* を利用したピークサービス向上の取り組み

インテル® DAAL による R の線形回帰の高速化
高度に最適化されたオープンソース ・ パッケージを使用してより正確に予測コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

31

40

48

58

The Parallel Universe

3

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

C90 と Julia
1993 年に、 私が博士課程修了後の研究を行っていた研究所では、 Cray* C90 スーパーコンピューターにアクセスしていました。 このシステムの利用競争率は凄まじく、 C90 のアーキテクチャーを活用していないプログラムは別のシステムで実行するように、 とストレートに言われたものです。 C90 はベクトル・プロセッサーであったため、 我々はコードをベクトル化する必要がありました。 コンパイラーのレポートを調べて必要なコード修正に時間をかけることで、 パフォーマンスが大幅に向上したことを覚えています。 ベクトル化は、 マルチコア時代では並列化の最前線から一歩引いてしまいましたが、 この最適化手法が重要であることに変わりはありません。 「ベクトル化が再び重要に」 では、 Robert H. Dodds Jr. イリノイ大学名誉教授が、 最新のプログラミング ・ ツールを利用して実際のア
プリケーションをベクトル化する方法を説明します。
今号でも引き続き、 OpenMP* 20 周年の特別記事として、 Livermore Computing の CTO であり、 OpenMP*
言語委員会の現在の委員長である Bronis R. de Supinski 氏から寄せられた論説を掲載します。 Bronis 氏は、「OpenMP* 20 周年」 の中で、 OpenMP* の概念と発展、 およびその将来についての見解を述べています。 20
周年を迎えてもなお、 OpenMP* は現代的なアーキテクチャーとともに発展を続けています。
私は Perl マニアになる前は Fortran マニアでしたが、 今は Python* マニアです。 最近、 私は Julia と呼ばれる新しいプログラミング言語に触れる機会がありました。 そこで、 いくつか時間のかかるデータ処理アプリケーショ
ンを、 できるだけ行単位での変換を心がけながら、 Python* から Julia に書き直しました。 これらは Julia の得意とする大量の数値計算を行うアプリケーションではなく、 テキストマイニングのデータセットを準備するストリング
操作アプリケーションでしたが、 パフォーマンスの向上は衝撃的なものでした。 私は Python* とその膨大なエコシステムを手放す気はまだありませんが、Julia には大いに注目しています。Julia 言語と機能の概要は、「Julia: スー
パーコンピューティング向け高水準言語」 をご覧ください。

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

4

この号の注目記事、 「インテル® System Studio による自動運転のチューニング」 では、 インテル® System
Studio のツールが提供する組込みシステムやコネクテッド・デバイス開発者向けの統合開発環境で、 ビルド、 デバッ
グ、 パフォーマンスや消費電力のチューニングを行う方法を紹介します。 エッジ ・アプリケーションのチューニング
をテーマとする別の記事、 「クラウドおよびエッジ ・ アプリケーション向けの高速データ圧縮コードのビルド」
では、 インテル® IPP を利用してデータ圧縮を高速化する方法を説明します。
前号の The Parallel Universe で述べたように、 R は私のお気に入りの言語ではありませんが、 R は優れた言語です。 「インテル® DAAL による R の線形回帰の高速化」 では、 R のデータ解析アプリケーションでインテル® DAAL
を活用する方法を説明します。 最後に、 この号の締めくくりとして、 「インテル® C++ コンパイラーによる MySQL* の最適化」 では、 プロシージャー間の最適化により、 データ ・ サイエンティストにとって重要なアプリケーションである、
MySQL データベースのパフォーマンスを大幅に向上する方法を紹介します。

今後についてThe Parallel Universe の将来の号では、 不揮発性メモリー、 IoT 開発、 インテル® アドバンスト ・ ベクトル ・
エクステンション (インテル® AVX ) 命令セットなど、 さまざまなトピックについて取り上げる予定です。
Henry A. Gabb
2017 年 7 月

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

5

インテル® System Studio による自動運転のチューニング
インテル® GO™ 車載機器用ソフトウェア開発キットが提供する車載機器用ソリューション
開発者向け統合ソリューション環境
Lavanya Chockalingam インテル コーポレーション ソフトウェア ・ テクニカル ・ コンサルティング ・ エンジニア

IoT (モノのインターネット) は、 クラウドに接続されたスマートデバイスの集合です。 「モノ」 は、 スマートウォッ
チやスマートフォンのように小さくシンプルなものにも、 自動車のように大きく複雑なものにもなりえます。 実際に、 自動車は世界で最もインテリジェントなコネクテッド ・ デバイスの 1 つとして急速に普及しており、 センサー ・
テクノロジーと強力なプロセッサーを使用して、 周囲の状況を感知して応答します。 自動車を動作させるには、
複雑なテクノロジーの組み合わせが必要となります。
•• LIDAR、 ソナー、 レーダー、 光信号に反応するセンサー•• 無数のデータポイントを収集するセンサー ・ フュージョン ・ ハブ•• データを処理するマイクロプロセッサー•• データをインテリジェントで有益なものにする大量の計算能力が要求されるマシンラーニング ・ アルゴリズム

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

6

これらの自動車革新における大きなチャンスを実現することは、 運転の概念を変えるだけでなく、 社会を変える可能性を秘めています。

インテル® GO™ 車載機器用ソフトウェア開発キット (SDK)自動車からクラウド (およびそれらの接続) には、 ハイパフォーマンス・プラットフォーム、 ソフトウェア開発ツール、
データセンター向けのテクノロジーを含む、自動運転ソリューションのニーズがあります。インテル® GO™ オートメー
テッド ・ ドライビング ・ ソリューションにより、 インテルは、 コンピューティング、 コネクティビティー、 クラウドにおける深い専門知識を自動車業界にもたらします。
グローバルな規模の自動運転は、 従来の自動車における高性能センサーやコンピューターの利用をはるかに超えるものであり、 データサービスとコネクティビティーの広範なインフラストラクチャーを必要とします。 このデー
タは、周囲を正確に感知して安全に応答する能力を絶え間なく向上するため、すべての自律走行車と共有されます。
データセンター、 道路上の構造物、 および不特定の車と通信を行うには、 広範なデータセンター ・ サービスとともに、 秒単位で大量のデータを受信、 ラベル付け、 処理、 格納、 転送できる、 広帯域幅で、 信頼性の高い双方向通信を自律走行車に実装する必要があります。 自動運転システム内のソフトウェア ・スタックは、 電力消費を最小限に抑えながら、 要求の厳しいリアルタイム処理要件を効率良く処理できなければなりません。
インテル® GO™ 車載機器用 SDK は、 さまざまなツールにより、 開発者やシステム設計者がハードウェアの能力を最大限に引き出せるように支援します。
•• 知覚、 融合、 意思決定に必要なミドルウェアとアルゴリズムを迅速に開発できる、 コンピューター・ビジョン、 ディー
プラーニング、 OpenCL* ツールキット•• ディープラーニングの訓練および環境モデリングの 「グラウンドトルース」 を作成する、 センサーデータのラベル
付けツール•• 機能的安全性に準拠したワークフローに沿ってフルスタックの最適化と迅速な開発を可能にする、 自動運転を対象としたパフォーマンス ・ ライブラリー、 最先端のコンパイラー、 パフォーマンス ・アナライザー、 消費電力アナライ
ザー、 デバッガー•• 開発者の学習に必要な期間を短縮する、 サンプル ・ リファレンス ・ アプリケーション (車線変更の検出や物体回避など)

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

7

インテル® System Studio
インテルは、 自動運転ソリューションの開発期間を短縮するソフトウェア開発ツールも提供しています。 インテル®
System Studio は、 開発のペースを早めると同時にハードウェアの能力を最大限に引き出す、 コンパイラー、 パ
フォーマンス・ライブラリー、消費電力アナライザー、パフォーマンス・アナライザー、デバッガーを含む、さまざまなツールを開発者に提供します。 次世代の優れた電力効率、 ハイパフォーマンス、 信頼性を達成するための高度なシス
テムツールとテクノロジーを組込み / モバイル機器の開発者にもたらす統合ツールスイートです。 次のような作業向けのツールを含みます。
•• コードのビルドと最適化•• コードのデバッグとトレース (不具合を分離して解決)•• 消費電力、 パフォーマンス、 正当性についてコードを解析

コードのビルドと最適化
インテル® C++ コンパイラー : 計算負荷の高いコードをインテル® HD グラフィックスにオフロードできる、 ハイパ
フォーマンスな、 最適化 C/C++ クロスコンパイラー。
• インテル® マス ・ カーネル ・ ライブラリー (インテル® MKL): 高度に最適化された線形代数、 高速フーリエ変換(FFT)、 ベクトル演算、 統計関数のセット。
• インテル® スレッディング ・ ビルディング ・ ブロック (インテル® TBB): 組込みシステムのパフォーマンスを向上する
C++ 並列コンピューティングのテンプレート。
• インテル® インテグレーテッド・パフォーマンス・プリミティブ (インテル® IPP): 一般的な信号 / 画像処理、コンピューター ・ ビジョン、 データ圧縮、 暗号化、 ストリング操作を含む、 高度に最適化されたさまざまな機能を提供するソ
フトウェア ・ ライブラリー。

コードのデバッグとトレース (不具合を分離して解決)•• インテル® System Debugger: OS カーネル ・ ソフトウェア、 ドライバー、 ファームウェアをソースレベルでデバッグできるシステムデバッグ機能と Eclipse* プラグインによるシステムトレース機能 (インテル® Trace Hub にアクセスしてトレースビューアーで高度な SoC ワイドの命令とデータイベントをトレース) を含む。
•• GNU* Project Debugger (英語): インテル® アーキテクチャー ・ ベースのシステムでネイティブおよびリモートにア
プリケーションをデバッグする、 インテルにより拡張された GDB。

消費電力、 パフォーマンス、 正当性についてコードを解析• インテル® VTune™ Amplifier: シリアル ・アプリケーションおよびマルチスレッド・アプリケーションを開発するユー
ザー向けのソフトウェア ・ パフォーマンス解析ツール。
• インテル® Energy Profiler: SoC Watch ツールを使用してターゲット ・プラットフォーム上で収集した消費電力関連のデータを解析する、 プラットフォーム全体の消費電力アナライザー。
• インテル® Performance Snapshot (英語): パフォーマンス最適化の可能性を素早く簡単に確認できるツール。
• インテル® Inspector: 組込みプラットフォームでシリアル ・アプリケーションおよびマルチスレッド ・アプリケーションを開発するユーザー向けのダイナミック ・メモリーとスレッドのエラーチェック ・ ツール。
• インテル® グラフィックス ・ パフォーマンス ・ アナライザー : CPU/GPU ワークロードを最適化するための、 リアル
タイムのシステムレベル ・ パフォーマンス ・アナライザー。

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

開発者の

秘密
兵器

インテル® System Studio で比類なきパフォーマンスを実現
ファクトリー ・ オートメーションがかつてなく直感的に。 検証サイクルを短縮しシステム全体の効率を最大化します。 今すぐ始めましょう。

正確に自動化 ›コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。
Intel、 インテル、 Intel ロゴは、 アメリカ合衆国および / またはその他の国における Intel Corporation の商標です。
* その他の社名、 製品名などは、 一般に各社の表示、 商標または登録商標です。
© Intel Corporation

9

パフォーマンスの最適化
高度な hotspot 解析
行列乗算は自動運転で一般的に使用される操作です。 インテル® System Studio のツール、 特にパフォーマンス ・
アナライザーとライブラリーは、 パフォーマンスを最大限に引き出すのに役立ちます。 入れ子の for ループで構成される行列乗算の実装例について考えてみます。
void multiply0(int msize, int tidx, int numt, TYPE a[][NUM], TYPE b[][NUM], TYPE
c[][NUM], TYPE t[][NUM]){
int i,j,k;// 基本的なシリアル実装
for(i=0; i<msize; i++) {for(j=0; j<msize; j++) {for(k=0; k<msize; k++) {c[i][j] = c[i][j] + a[i][k] * b[k][j];}}}}

高度な hotspot 解析は、 パフォーマンス ・ クリティカルなコードセクション (hotspot) を迅速かつ簡単に特定できます。 インテル® VTune™ Amplifier による命令ポインターの周期的サンプリングは、 アプリケーションが時間を費やしているコードの場所を特定します。 ある関数で多くの時間を費やす理由は、それ自体が遅いコードであるか、その関数が頻繁に呼び出されることです。 そのような関数をスピードアップすると、アプリケーション全体のパフォー
マンスに大きな影響を与えます。
インテル® VTune™ Amplifier を使用して行列乗算コードで高度な hotspot 解析を実行したときの経過時間は22.9 秒でした (図 1)。 CPU は 22.6 秒実行されていました。 CPI レート (命令あたりのサイクル数) 1.142 は問題であるとフラグが付いています。 最新のスーパースカラー ・プロセッサーは、 1 サイクルあたり 4 つの命令を発行できるため、 CPI の理想値は 0.25 ですが、 レイテンシーの長いメモリー命令、 分岐予測ミス、 フロントエンドの命令スタベーションのような、 パイプラインのさまざまな要因により、 実際に観測される CPI は高くなります。 1 以
下の CPI は適切であると見なされますが、 異なるアプリケーション ・ ドメインでは予想値も異なります。 この例では、 アプリケーションをさらに解析して CPI が低いかどうかを確認します。 インテル® VTune™ Amplifier の高度
な hotspot 解析は、 最適化を考慮すべき上位 5 つの hotspot 関数も示します。

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

10

1

最適化前の経過時間と上位の hotspot

CPU 使用率
図 2 に示すように、 オリジナルコードの解析では、 88 の論理 CPU のうち 1 つのみが使用されています。 これは、サンプルコードを並列化できれば、 大幅なパフォーマンス向上が期待できることを意味します。

2

CPU 使用状況

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

11

次のようにサンプルコードを並列化するだけで、 12 倍のスピードアップを達成でき (図 3)、 CPI も 1 未満になり、大幅に改善されました。
void multiply1(int msize, int tidx, int numt, TYPE a[][NUM], TYPE b[][NUM], TYPE
c[][NUM], TYPE t[][NUM]){
int i,j,k;// 基本的な並列実装#pragma omp parallel for
for(i=0; i<msize; i++) {for(j=0; j<msize; j++) {for(k=0; k<msize; k++) {c[i][j] = c[i][j] + a[i][k] * b[k][j];
}
}
}
}

3

並列化によるパフォーマンスの向上

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

12

全般解析
基本 hotspot 解析または高度な hotspot 解析を使用してコードの hotspot を特定した後、 全般解析を実行して、コア ・ パイプライン上のコードの効率を理解します。 インテル® VTune™ Amplifier の全般解析では、 特定のクライ
アント ・アプリケーションを解析するため主要なイベントを収集して、 メトリックに関連する事前定義の比率を計算し、 ハードウェアレベルのパフォーマンス問題を特定します。 スーパースカラー ・プロセッサーは、 概念的に、
フロントエンド (命令セットのフェッチとデコード) とバックエンド (要求された計算の実行) に分割できます。 全
般解析は、 すべてのパイプライン ・スロットを 4 つのカテゴリーに分けます。
1. 発行されリタイアされた有効なワークを含むパイプライン ・スロット (リタイア)
2. 発行されキャンセルされた有効なワークを含むパイプライン ・スロット (不正なスペキュレーション)
3. フロントエンドの問題により有効なワークで満たすことができなかったパイプライン ・スロット (フロントエンド依存)
4. バックエンドの滞りにより有効なワークで満たすことができなかったパイプライン ・スロット (バックエンド依存)

図 4 は、 インテル® VTune™ Amplifier を使用して並列化したサンプルコードを全般解析した結果を示しています。 パイプライン ・スロットの 77.2% はバックエンドの問題でブロックされていることに注意してください。 ド
リルダウンすると、 これらのバックエンドの問題が発生しているソースコードが表示されます (図 5、 49.4% +27.8% = 77.2% がバックエンド依存)。 メモリーの問題と L3 レイテンシーが非常に高くなっています。 メモリー
依存メトリックは、 メモリー ・ サブシステムがパフォーマンスに与える影響を示します。 L3 依存メトリックは、
CPU が L3 キャッシュでストールしている比率を示します。 キャッシュミス (L2 ミス /L3 ヒット) を回避すると、レイテンシーが軽減され、 パフォーマンスが向上します。

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

13

4

全般解析の結果

5

問題を特定

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

14

メモリーアクセス解析
インテル® VTune™ Amplifier のメモリーアクセス解析は、 NUMA (不均等メモリーアクセス) や帯域幅に制限されるアクセスなどのメモリーに関連する問題を識別し、 パフォーマンス・イベントをメモリー・オブジェクト (データ構造)に紐付けます。 この情報は、 メモリー割り当てと解除のインストルメンテーションと、 シンボル情報からスタティッ
ク / グローバル変数を識別することで提供されます。
[Function/Memory Object/Allocation Stack (関数 / メモリー ・ オブジェクト / 割り当てスタック)] のグルー
プ化オプション (図 6) を選択して、 パフォーマンスに影響を与えるメモリー ・ オブジェクトを識別できます。
multiply1 関数でリストされた 3 つのオブジェクトのうち、 1 つのオブジェクトのレイテンシーが非常に高くなっています (82 サイクル)。 このオブジェクトをダブルクリックすると、 ソースコードが表示され、 配列 “b” のレイテ
ンシーが最も高いことが分かります。 これは、 配列 “b” が列優先順を使用しているためです。 入れ子のループを交換すると、アクセスが行優先順に変更されることでレイテンシーが軽減され、パフォーマンスが向上します (図 7)。

6

パフォーマンスに影響しているメモリー・オブジェクトを特定

7

全般解析の結果

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

15

このコードはまだバックエンド依存ですが、メモリー依存ではなくなり、コア依存のみになったことが分かります。ハー
ドウェアの計算リソース不足やソフトウェア命令の依存性は、 どちらもコア依存に分類されます。 つまり、 マシンがアウトオブオーダー ・ リソースを使い果たしていないことが分かります。 特定の実行ユニットへの要求が高いか、 プ
ログラムのデータ / 命令フローにパフォーマンスを制限する依存性があります。 この例では、 ベクトル処理機能が効率良く使用されておらず、 浮動小数点スカラーまたはベクトル命令が一部のベクトル処理機能のみ使用していることを示しています。 この問題は、 コードをベクトル化することで解決できます。
別の最 適化オプションは、 行列乗算を含む、 数学演算に最 適化およびスレッド化された実装を提供する、
インテル ® MKL を使用することです。 dgemm ルーチンは、 2 つの倍精度行列を乗算します。
void multiply5(int msize, int tidx, int numt, TYPE a[][NUM], TYPE b[][NUM], TYPE
c[][NUM], TYPE t[][NUM]){
double alpha = 1.0, beta = 0.0;}

cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans,
NUM, NUM, NUM,
alpha, (const double *)b,
NUM, (const double *)a,
NUM, beta, (double *)c, NUM);

画像のサイズ変更のパフォーマンス解析とチューニング
画像のサイズ変更は自動運転では一般的な操作です。 例として、 オープンソースの OpenCV* の画像のサイズ変更に対して、 インテル® VTune™ Amplifier の高度な hotspot 解析を実行します (図 8)。 経過時間は 0.33 秒で、最上位の hotspot は cv:HResizeLinear 関数 (合計 CPU 時間は 0.19 秒) であることが分かります。

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

16

8

高度な hotspot 解析

インテル® IPP は、 画像処理、 信号処理、データ処理 (データ圧縮 / 展開および暗号化) アプリケーション向けの、高度に最適化された実用的なビルディング・ブロックを提供します。 これらのビルディング・ブロックは、 インテル®
ストリーミング SIMD 拡張命令 (インテル® SSE )、 インテル® アドバンスト・ベクトル・エクステンション (インテル®
AVX )、 インテル® AVX2 命令セットを使用して最適化されています。 図 9 は、 インテル® IPP を活用した画像のサイズ変更の解析結果です。 経過時間が半分になったことが分かります。 また、 1 つのコアのみ使用されているため、 インテル® TBB の並列処理を使用してさらにパフォーマンスを向上できる可能性があります。

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

17

9インテル® VTune™ Amplifier でコードをチェック

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

18

まとめ
インテル® GO™ 車載機器用 SDK のインテル® System Studio ツールは、 車載機器用ソリューションのコードのビルド、 デバッグ、 パフォーマンスや消費電力のチューニングを可能にする、 統合開発環境を提供して、 システム
および組込み開発者が最も困難なアルゴリズムの課題に対応することを支援します。
•• ソフトウェア開発を促進して競争力の高い自動運転車を迅速に市場に提供できるようにします。
•• 複雑な自動運転 (AD)、 先進運転支援システム (ADAS)、 ソフトウェア定義コックピット (SDC) システムの不具合を迅速に特定して解決できるように支援します。
•• パフォーマンスの向上と消費電力の削減を支援します。

これらがすべて 1 つの使いやすいソフトウェア ・ パッケージで提供されます。

BLOG HIGHLIGHTS
インテル® Xeon Phi™ プロセッサー ・ ベースのシステムにおける古典的な行列乗算
アルゴリズムのパフォーマンス
SERGEY KOSTROV (INTEL) ›2 つの行列の行列乗算 (MM) は、線形代数で最も基本的な演算の 1 つです。MM のアルゴリズムは非常に単純で、任意のプログラム言語で簡単に実装でき、 異なる最適化手法を適用するとパフォーマンスは大幅に向上します。
正方密行列の積を計算する古典的な行列乗算アルゴリズム (CMMA) のいくつかのバージョンを 4 つのテストプロ
グラムで評価します。 これらの CMMA のパフォーマンスを、 インテル® マス ・ カーネル ・ ライブラリー (インテル®
MKL) の高度に最適化された ‘cblas_sgemm’ 関数と比較します。 テストはインテル ® Xeon Phi ™ プロセッサー
7210 を搭載したコンピューター・システム (Linux* Red Hat* オペレーティング・システム、 ‘All2All’ クラスター
モード、 ‘Flat’、 ‘Hybrid 50-50’、 および ‘Cache’ MCDRAM モード) で行われました。
この記事の続きはこちら (英語) でご覧になれます。

インテル® System Studio の無料体験版のダウンロード ›コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

19

OpenMP* 20 周年

並列プログラミングを C/C++ および Fortran プログラマーが利用しやすいものにBronis R. de Supinski Livermore Computing CTO

私は、 20 年という歳月を経て OpenMP* がようやく成人したと感じています。 OpenMP* 20 周年のさまざまなイベントは、 OpenMP* 仕様の原点と発展を改めて見直す機会を与えてくれました。 OpenMP* 言語委員会の委員長として (OpenMP* 3.0 のリリース直後から約 9 年間務めています)、 この回顧録ならびに OpenMP*
組織の現況と将来の計画を発表する機会が得られたことを嬉しく思っています。 私は、 OpenMP* がそのルーツに忠実なまま、 今後 20 年間さらなる発展を遂げることに、 皆さんも同意されることを期待しています。
OpenMP* は、 ループベースの共有メモリー並列処理に対応するため、 多くのコンパイラー ・メーカーがまだ標準化されていないディレクティブをサポートしていた時代に生まれました。 これらのディレクティブは効果的でしたが、 重要な要件である移植性に欠けていました。 これらの実装固有のディレクティブは、 構文 (スペリング)が異なっているだけでなく、しばしばセマンティクスにも微妙な違いがありました。この欠点に気付いていたロー
レンス ・ リバモア国立研究所の Mary Zosel 氏は、 各メーカーと密接に協議して、 共通の構文とセマンティクス
について合意を取り付け、OpenMP* 1.0 の提供にこぎつけました。 さらに、彼らは OpenMP* の権利を所有し、OpenMP* 仕様を管理する組織を創立しました。

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

20

多くの人は、 OpenMP* のルーツを、 単純に最初の仕様で標準化されたループベースの共有メモリー ・ ディレク
ティブとしてとらえているでしょう。 私は、 OpenMP* のルーツを、 コンパイラー ・メーカーとシステムができるだけ移植性の高いパフォーマンスを提供することを求めるユーザー組織による、 移植性のあるディレクティブ ・ ベースの並列化と最適化 (プロセス内に制限された) をサポートする取り組みであると考えています。 OpenMP* は、 コン
パイラーが (スタティック) 解析により引き出すことが困難または不可能であると判断した、 アプリケーションに対するパフォーマンスを明示的に表現するプログラマー向けのメカニズムである、 と私は思っています。 組織的には、OpenMP* は、 すべての主要コンパイラー ・メーカー並びに活発で成長を続けるユーザー組織を含む多くの会員を擁し、 活気に満ちた活動を行っています。
技術的には、 OpenMP* 仕様は、 利用可能なループベースの並列処理ディレクティブを統一するという本来の目標を達成しました。 現在も、 その目的のために、 単純で、 適切に定義された構文の改良を続けています。 さらに、
OpenMP* は、 ループを結合する機能や、 並列化されたコードを実行するスレッドの配置を制御する機能など、 ディ
レクティブの改良も続けています。 これらの構文は、 共有メモリー ・アーキテクチャーおよびコンパイラー全体にわたって一貫した強力なパフォーマンスを達成し、 OpenMP* 誕生の動機となった移植性を提供します。
OpenMP* の発展とともに、 いくつかの新たな並列処理も採用されました。 私は、 コミュニティーに参加する人々がタスクベースの並列処理のメカニズムの標準化が必要であるという話をしているのを聞くとうんざりします。
OpenMP* は 9 年も前から標準化されたメカニズムを提供しています。 2008 年に、 完全なタスクベースのモデルを採用した OpenMP* 3.0 仕様がリリースされました。 OpenMP* のタスク実装はまだ改善できると私は考えていますが、 現在はどちらとも決めかねる問題に直面しています。 一貫して強力なパフォーマンスを提供するモデルが実装されれば OpenMP* タスクを使用する、 とユーザーが述べているのをよく聞きます。 また、 モデルの採用が進めばタスクの実装を最適化する、 とメーカーが述べているのもよく聞きます。 別の視点から見た OpenMP* タス
クモデルの問題は、 1 つのアプリケーションですべてを使用できるように、 一連の並列化手法に一貫した構文とセマンティクスを提供するという、OpenMP* の長所によるものです。 このような一般化のサポートには、オーバーヘッ
ドがつきものです。 しかし、 モデルを改良することで、 オーバーヘッドを多少緩和できます。 例えば、 OpenMP* 3.1
では、 複雑なコンパイラー解析や複雑なプログラム構造に依存しない、 最小タスク粒度を指定する final 節 (および関連する概念) が追加されています。 我々は、 将来の OpenMP* 仕様に取り組むとともに、 OpenMP* タス
クのオーバーヘッドを軽減する方法を見い出そうとしています。

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

21

OpenMP* 4.0 リリースでは、 別の観点から並列処理をサポートしました。 現在の OpenMP* には、 デバイス構文によるアクセラレーター ・ ベースの並列化と SIMD (またはベクトル) 並列処理のサポートが含まれています。 SIMDのサポートは、 OpenMP* の原点を思い起こさせるものです。 実装固有のディレクティブによる SIMD 並列処理のサポートは広く普及しており、 ivdep 形式が最もよく採用されていました。 しかし、 サポートされている節はさ
まざまで、 一部のコンパイラーではディレクティブの記述方法も異なっていました。 さらに、 セマンティクスもわず
かに異なることが多く、 ディレクティブが 1 つのコンパイラーで正しく、 別のコンパイラーで正しくないことがありました。 20 年前に OpenMP* の誕生によりループベースのディレクティブの問題が解決したように、 SIMD 構文がOpenMP* で採用されたことで、 これらの問題のほとんどは解決しました。 もちろん、 SIMD ディレクティブの最初の実装は完璧ではなく、 我々は改良を続けています。 例えば、 OpenMP* 4.5 では、 ユーザーが SIMD ベクトル長を指定できる simdlen 節が追加されました。
OpenMP* の target 構文は、 構造化ブロックの計算をデバイスにオフロードするように指定します。 OpenMP*
4.0 仕様で追加されたこの構文は、 GPU のようなデバイス上での効率的な並列処理をサポートします。 重要なことは、 すべての OpenMP* 構文は target 領域内で使用できることです。 つまり、 ディレクティブ ・ ベースの並列化における数々の進歩をさまざまなデバイスで活用することができます。 特定の種類のデバイスと並列化するアルゴ
リズムに対して最適な並列処理手法を考える必要はありますが、 OpenMP* 構文の直交性は、 複数のアーキテク
チャーをターゲットにするプログラムの移植性を大いに高めるでしょう。
我々は、 現在、 2018 年 11 月に公開予定の、 OpenMP* 5.0 仕様に取り組んでいます。 すでにいくつかの大幅な拡張を採用しました。 OpenMP* TR4 は、 2016 年 11 月以降の OpenMP* 5.0 における変更点を文書化したものです。 また我々は、 これまでの進捗を文書化した新しい TR5 を 11 月に公開する予定です。 TR4 の最も重要な追加機能は、 OpenMP* をツール ・ インターフェイスで拡張する OMPT です。 私は、 OpenMP* 5.0 では、OpenMP* アプリケーションのデバッグを促進するツール ・ インターフェイス、 OMPD が追加されると予想しています。 TR4 では、 多くの拡張が採用されましたが、 その中でも注目すべきはタスク ・ リダクションの追加でしょう。
OpenMP* 5.0 では、 TR4 に含まれていなかったいくつかの重要な拡張を追加する予定です。 注目すべき点として、OpenMP* は複雑なメモリー階層のサポートを大幅に強化します。 まず、 私は、 このメモリー割り当てメカニズム
が TR5 に含まれることを期待しています。 このメカニズムは、 複数の種類のメモリー (例えば、 DDR4 と HBM) を含むシステムで、 特定の変数や動的割り当てにどのメモリーを使用すべきかを指定する直感的なインターフェイスをプログラマーに提供します。 さらに、 OpenMP* が複雑なデータ構造のディープコピーをサポートする、 強力なシリアル化 / 逆シリアル化インターフェイスを提供することを期待しています。 このインターフェイスは、 デバイス構文によるデータ依存レイアウトの変換と関連する最適化を可能にします。

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

22

前述のとおり、OpenMP* 組織は健全です。 我々は、過去数年間、新しいメンバーとしてコンパイラー・メーカーとユー
ザー組織の両方を迎えてきました。 現在、 さらに参加の門戸を広げるために、 OpenMP* 規約の変更について議論しています。 OpenMP* の将来の構想に興味を持たれている多くの方々の参加をお待ちしています。 OpenMP*の詳細は、 openmp.org (英語) を参照してください。
Bronis R. de Supinski 氏は、 ローレンス ・ リバモア国立研 究 所 のスーパーコンピューティング ・ センター、
Livermore Computing の CTO であり、 OpenMP* 言語委員会の委員長でもあります。
この記事は、 米国政府機関の後援を受けた研究の説明として準備されたものです。 米国政府、 ローレンス ・ リバモア国立研究所、 およびこれらの機関の職員のいずれも、 本記事で示された情報、 機器、 製品、 プロセスの正確性、 完全性、 有用性について、 あるいはそれらの使用が私有の権利を侵害しないことについて、 明示的であれ黙示的であれ、 いかなる保証も行わず、いかなる法的責任も負いません。 本記事の商標名、 商標、 メーカーによる特定の商用製品、 プロセス、 サービスに対する参照は、 必ずしも米国政府あるいはローレンス ・ リバモア国立研究所による支持、 推薦、 賛同を意味するものではありません。 本記事で示された著者の意見および見解は、 必ずしも米国政府あるいはローレンス ・ リバモア国立研究所の意見および見解を述べたり反映したものではなく、 広告や製品を推奨する目的に使用されないものとします。 この研究、 LLNL-MI-732158 は、 契約 DE-AC52-07NA27344 の下で、 ローレンス ・ リバモ
ア国立研究所により、 米国エネルギー省の後援の下に行われました。

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

23

Julia: スーパーコンピューティング
向け高水準言語科学計算の新しい壁を乗り越える Julia プロジェクト

Ranjan Anantharaman、 Viral Shah、 Alan Edelman Julia Computing

ハイパフォーマンス ・コンピューティング (HPC) は、 科学的発見の最先端で活躍しています。 科学者は、 分散環境の何百万ものコア上でシミュレーションを日常的に行っています。 主要なソフトウェア ・スタックは、 一般的に、 C/
C++ や Fortran のように静的にコンパイルされる言語と OpenMP*/MPI の組み合わせで構成されています。 この
ソフトウェア・スタックは、 時間をかけて実証された組み合わせであり、 HPC 業界の至るところで使用されています。
その主な理由は、 メモリー使用量を抑えつつ、 利用可能な計算リソースをすべて使用する効率の高さです。 このレベルの効率性は、 Python*、 Octave、 R のような、 「高水準」 スクリプト言語では達成できないものでした。 これらの言語は迅速なプロトタイプ作成を促進する高生産性環境として設計されており、 大規模な計算クラスター上で効率良く動作するようには設計されていないことが主な原因です。 しかし、 そのように設計にすべきでない技術的な根拠はなく、 科学計算向けのツールに問題があることを示しているに過ぎません。

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

24

テクニカル ・ コンピューティング向けの新しい言語である Julia は、 この問題に取り組むことを目的としています。
Julia は、Python* や Octave のように可読性が高く、C のように働きます。マルチスレッドおよび分散コンピューティ
ングに対応したビルトイン・プリミティブを備えており、 何百万ものコアにアプリケーションをスケーリングできます。
それでは、なぜほかの高水準言語では同じことができないのでしょうか ? 可読性が高く、効率性に優れた Julia は、どんな点がユニークなのでしょう ?
その答えは、 Julia が型推論とコード特殊化を組み合わせて優れたマシンコードを生成しているためです。 関数呼び出しで生成されるアセンブリー ・コードを生成する Julia マクロ、 @code_native を使用してみましょう。 次に例を示します。
julia> @code_native 1 + 1.section__TEXT,__text,regular,pure_instructions
Filename: int.jl
pushq %rbp
movq %rsp, %rbp
Source line: 32
leaq (%rdi,%rsi), %rax
popq %rbp
retq
Source line: 32
nopw (%rax,%rax)

この例は、 Julia が 2 つの整数を加算するときに生成されるアセンブリー ・コードを示しています。 Julia は加算に対し適切なアセンブリー命令を選んでおり、 オーバーヘッドは事実上ありません。
次のコードは、 2 つの倍精度浮動小数点数の加算を示しています。
julia> @code_native 1. + 1.
.section__TEXT,__text,regular,pure_instructions
Filename: ﬂoat.jl
pushq %rbp
movq %rsp, %rbp
Source line: 240
addsd %xmm1, %xmm0
popq %rbp
retq
Source line: 240
nopw (%rax,%rax)

ここでは 2 つの浮動小数点数を加算するため、Julia は異なる命令 addsd を自動的に選んでいます。この違いは、
コンパイラーにより推定された入力の型に応じて、 関数 “+” の 2 つのバージョンが生成されるためです。 これにより、 ユーザーは高水準コードを記述し、 Julia に入力の型と出力の型を推論させて、 それらの入力の型に対応したバージョンの関数をコンパイルすることができます。 このアイデアが Julia を高速にしています (図 1)。

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

25

1

C と比較した Julia の相対ベンチマーク時間 (小さいほど良い)。C のパフォーマンス = 1.0。
ベンチマーク・コードは、GitHub リポジトリー (英語 ) から入手できます。

Julia のユニークな機能は、 データサイエンスと数値計算の 2 言語問題 (英語) を解決しました。 その結果、 Julia
は 航空宇宙 (英語) から 金融 (英語) まで、 さまざまな業界 (英語) で利用されるようになりました。
これが、 業界と協議して、 コミュニティーにおける Julia の採用を進めることを目的とした、 Julia Computing (英語)の設立につながりました。 Julia Computing の代表的な製品の 1 つ、 JuliaPro (英語) は、 IDE、 デバッガー、 100を超えるテスト済みのパッケージを含む、 Julia ディストリビューションです。 JuliaPro は、 マルチコアおよび最新のインテル® プロセッサー向けに BLAS 操作を高速化および最適化するため、 インテル® MKL を同梱する予定です。

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

26

Julia の並列コンピューティング
Julia は、 ベクトル化 (SIMD)、 マルチスレッド、 分散コンピューティングと、 すべてのレベルの並列コンピューティン
グに対応したビルトイン ・プリミティブを備えています。
例として、 自明な並列性を持つシミュレーションを考えてみます。 π の反復計算には、 0 から 1 の範囲の乱数の生成と、 単位円内に入る数と入らない数の比率の計算が含まれます。 この単位正方形と単位円の領域の比率を使用
して、π を計算することができます。 次の Julia コードは、@parallel 構文を使用しています。 レデューサー “+” は、すべての Julia プロセスで並列に計算された最終的な式の値を合計します。
addprocs(2)# 2 つの Julia ワーカープロセスを追加

function parallel_π(n)in_circle = @parallel (+) for i in 1:nx = rand()y = rand()Int((x^2 + y^2) < 1.0)
end
return (in_circle/n) * 4.0
end# <-- ワークを分割

parallel_π(10000)

Julia は、ワークをワーカープロセスにオフロードします。ワーカープロセスは、結果を計算して Julia マスターに戻し、Julia マスターはリダクションを実行します。 この 1 方向通信モデルは、 任意の計算領域を異なるワーカープロセ
スに割り当てることができます。
より興味深い利用例では、 異なるプロセッサーで 1 次方程式を解いた後、 出力をシリアル化してマスタープロセ
スに送ります。 スケーラブル ・ マシンラーニングは、 多くの独立した解を含む例の 1 つです。 図 2 は、 何百万もの映画レーティングを処理して予測を行う、 RecSys.jl (英語) のパフォーマンスを示しています。 このコードは、 協調フィルタリングの単純な反復法である、 Alternating Least Squares (ALS) (英語) と呼ばれるアルゴリズムをベースにしています。 解はほかの解に依存しないため、 このコードは簡単に並列化してスケーリングできます。 図 2 は、システムのスケーリング特性を示すパフォーマンス ・ グラフです。

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

27

2

ALS 推薦システムのスケーリング・グラフ: nprocs は、共有メモリーモードと分散モードではワーカープロセスの数、
マルチスレッド・モードではスレッド数を指します。

図 2 は、 マルチスレッド ・ モード (Julia MT )、 分散モード (Julia Distr)、 共有メモリーモード (Julia Shared) における Julia のスケーリング ・ パフォーマンスを示しています。 共有メモリーモードでは、 独立した Julia ワーカープロ
セス (スレッドではない) が共有アドレス空間にアクセスできます。 このグラフの興味深い点は、Julia の分散機能と、業界で広く採用されているスケーラブル解析フレームワーク Apache Spark* との比較です。 さらに興味深い点は、Julia はノード数が多くなっても適切にスケーリングできるという、 この実験の結果です。 では、 スーパーコンピュー
ティングで実際に行われているプロジェクトに話を移しましょう。

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

28

スケーリングで協力する : Celeste
Celeste プロジェクトは、 Julia Computing (Keno Fischer)、 インテル ・ ラボ (Kiran Pamnany)、 JuliaLabs@
MIT (Andreas Noack、 Jarrett Revels)、 ローレンス ・ バークレー国立研究所 (David Schlegel、 Rollin Thomas、Prabhat)、 カ リ フ ォ ル ニ ア 大 学 バ ー ク レ ー 校 (Jeffrey Regier、 Maximilian Lam、 Steve Howard、 Ryan
Giordano、 Jon McAuliffe) の共同プロジェクトです。 Celeste は、 統計的推測を使用した生成的階層モデルで、上空の光源を数学的に見つけて特徴付けます。 このモデルを利用して、 天文学者は、 スペクトルグラフのターゲッ
トとなる有望な銀河を識別し、 さらに調査の対象となる銀河を定義して、 暗黒エネルギー、 暗黒物質、 宇宙の形状の理解に役立てることができます。 実験に使用されたデータセットは Sloan Digital Sky Survey (SDSS) (図 3) と、
55 テラバイトのデータからなる 500 万を超えるイメージです。

3

Sloan Digital Sky Survey (SDSS) のサンプル

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

29

Julia のネイティブ並列コンピューティング機能を使用して、 研究者たちは、 ローレンス ・ バークレー国立研究所の National Energy Research Scientific Computing Center (NERSC) にある Cori スーパーコンピューターに搭載されている 8,192 のインテル® Xeon® プロセッサー ・コアで動作するようにアプリケーションをスケーリング
することができました。 イメージ解析の速度は 225 倍になり、 以前の数値よりも 3 桁多い、 20,000 を超える
(250GB の) イメージを処理できるようになりました。
この数値は、 256 ノード (1 ノードあたり 4 スレッド) までスケーリングできる、 Julia のネイティブ並列機能を使用して達成されました。 このスケーリング機能により、 Julia は、 HPC の世界で注目を集め、 C/C++ や Fortran のような主要言語と同じ地位を占めるようになりました。
インテル ・ ラボの Pradeep Dubey 氏は、 「Celeste では、 Python* や R ではまだ行うことができない (プロセスとスレッドの) ハイブリッド並列処理を使用して優れた効率を実現できた Julia の話が盛んに行われています。」 と述べています。
プロジェクトの次のステップは、 さらなるスケーリングとデータセット全体の処理です。 これには、 最新のインテル®
Xeon Phi™ プロセッサーおよびインテル® Xeon Phi™ コプロセッサーを利用することも含まれます。

新しい壁を乗り越える
Julia プロジェクトは、 2012 年に公表されてから大きな進歩を遂げており、 科学計算の新しい壁を次々に乗り越えています。 Julia は、 C/C++ と同じように高速でスケーラブルでありながら、 Python* の生産性を備えた言語であると見なされています。 Celeste プロジェクトは、 このアプローチにより、 Julia がクラスター上で適切にスケーリングできる最初の高生産性言語になれることを示しています。
Julia プロジェクトは、ユーザーベースが年々倍増しており、さまざまな業界で広く採用されています。 計算科学ツー
ルの進歩は、 次の時代の課題に取り組む科学研究にとっての吉報であるだけでなく、 迅速な革新サイクルやター
ンアラウンド ・ タイムにつながります。

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

30

効率良く動作する
高速なコードインテル® Parallel Studio XE のスピードは
コードに何をもたらすのか?
高速なプロファイル、高度なコンパイラー、最新のスレッド化およびベクトル化ツールにより、コードをさらに高速化できます。
インテル® Parallel Studio XE は、パフォーマンス・ボトルネックを解消し、コードを効率良く動作できるように支援します。

コードの推進力を高めよう ›コンパイラーの最適化に関する詳細は、最適化に関する注意事項を参照してください。
Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国における Intel Corporation の商標です。
* その他の社名、製品名などは、一般に各社の表示、商標または登録商標です。
© Intel Corporation.

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

31

ベクトル化が再び重要に

オープンソース ・ コード WARP3D がベクトル化に新たな関心が寄せられていることを実証

Robert H. Dodds Jr. イリノイ大学 名誉教授

各プロセッサー ・ コア上の SIMD (ベクトル) レジスターの幅が広くなり、 インテル ® アドバンスト ・ ベクトル ・ エ
クステンション 2 (インテル ® AVX2) では 4 つの倍精度、 インテル ® アドバンスト ・ ベクトル ・ エクステンション
512 (インテル ® AVX-512) では 8 つの倍精度を処理できるようになったことで、 ハイパフォーマンス・コンピュー
ティングの主力であるベクトル化が新たな重要性を持って再び脚光を浴びています。 ベクトル幅の拡張は、 特定のソフトウェア (例えば、 機械系の非線形動作をシミュレーションするための大規模な有限要素解析など) においてパフォーマンスを大幅に向上する可能性をもたらします。 オープンソースの研究用コード WARP3D (英語)
(GitHub (英語) からも入手可能) は、 そのようなシミュレーションに特化しており、 エネルギー生産や関連業界においてよく見られる重要なコンポーネントの安全性および寿命予測手法の開発をサポートします。 その対象分
野 (3D 非線形固体)、 オープンソース、 扱いやすいコードサイズ (1,400 ルーチン) は、 業界および学会の研究者にとって魅力的なものです。

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

32

WARP3D (英語) は、 並列コンピューティングの現在の階層を表しています : MPI でクラスター上の複数のノードにアクセスし、 OpenMP* で各ノードのスレッドを利用し、 各スレッドでベクトル化します。 複雑な動作 (例えば、 大きな部材を溶接する際に生じる内部応力など) を予測するための現実的なシミュレーションは、現在のコンピューター
による並列処理でも、 数時間を要します。 問題を解決する典型的な行列演算は、 並列コンピューティングの階層にうまくマップできます。 コアレベルでのベクトル化が進むことで、 並列に実行するスレッドと MPI ランク全体にわたってパフォーマンスが増加します。
この記事は、 WARP3D で実装されているベクトル化の概要を説明します。 過去 20 年にわたって開発されてきた WARP3D のコードは、 進化する Fortran の機能を採用しています。 Linux*、 Windows*、 macOS* 向けのオープンソース ・ ディストリビューションに含まれる実行ファイルのビルドには、 インテル ® Parallel Studio XE のコンポーネント (インテル ® Fortran コンパイラー、 インテル ® マス ・ カーネル ・ ライブラリー (インテル ® MKL)、
およびインテル ® MPI ライブラリー ) を使用しています。 WARP3D は、 非線形有限要素法を暗黙的に定式化するため、 増大する大規模な一次方程式のセットを解く必要があります。 インテル® MKL の PARDISO および
CPARDISO パッケージは、 このような計算で優れたパフォーマンスを提供します。 ここで紹介する例は、 ループ
レベルのパフォーマンスを簡単に詳しく調査できる、 新しいインテル ® Advisor 2017 のルーフライン解析機能についても触れています。

1

有限要素モデル

図 1 は、 フランジの 3D 有限要素モデルを要素のドメイン (MPI ランクごとに 1 つのドメイン) に分解し、 ドメイン内の要素をブロックに割り当てる処理を図解したものです。 モデルの各離散要素には、 関連するいくつかの小さな
通常の配列と一時配列 (例えば、 6x6、 24x24、 60x60、 6x60) があり、 中規模から大規模のモデルではそのような配列が数百万になります。
図 2A は、 要素データを格納する従来のマルチレベルの構造体配列 (AoS) で、 多くの場合 1 つの要素の配列がメモリー上に連続して配置されます。 概念的には便利そうに見えますが、 比較的小さな要素レベルの行列によって内部ループのベクトル長が制限され、 同じ配列型の要素全体を処理する際にキャッシュサイズの影響を考慮してチューニングするメカニズムが用意されていません。
代替手段として、 図 2B に示す要素剛性行列 Ke と Be (例) のブロック化されたデータ構造は、 2D と 3D の密配列を使用して配列構造体 (SoA) を定義し、 ブロックに関連付けられた要素数によって配列の 1 次元の大きさを設定します。 これは、 WARP3D ではスパン (span) と呼ばれ、 ブロック内の要素に対応するすべての Ke 行列と Be
行列はそれぞれメモリー上で連続して配置されます。

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

33

2A

従来の構造体配列

2B

代替のブロック化されたデータ構造

マスターリストでブロックの所有権をドメイン別に設定します。 次のシーケンスは WARP3D における MPI とOpenMP* によるスレッド並列処理の組み合わせの概念を示します。
c$OMP PARALLEL DO PRIVATE( blk )do blk = 1, number_ele_blks
if( blk_to_domain_map(blk) .ne. myrank ) cycle
call process_a_blk( blk )end doc$OMP END PARALLEL DO

WARP3D は、 単純なマネージャー / ワーカーモデルを使用して、 MPI ランク間のタスクを同期します。 上記のコードでは、 マネージャー (ランク 0) が、 すべてのワーカーが OpenMP* の並列ループを実行して、 それぞれが所有するブロックを処理することを保証します。 process_a_blk ルーチンは、 派生型で必要なブロック化された配列のワークを動的に割り当てます。 これはルーチンで private として宣言されているため、各スレッドでローカルです。 要素行列を作成 / 更新する複雑な複数レベルの計算ルーチンは、 ベクトル処理を意識してコーディ
ングされていますが、 OpenMP* や MPI ランタイム環境は考慮していません。 この要素ベースの計算のデータ
独立性は、有限要素法の重要な特徴です。 グローバル配列はスレッドによって読み取り専用としてアクセスされ、
1 つのベクトルに対する数ブロックのギャザー操作は、 $OMP ATOMIC UPDATE で同期します。 WARP3D のすべてのスレッド処理は、 数十のループ / ディレクティブのみによって達成されます。
Cray* ベクトルベース ・ コンピューターの登場は、 米国の国立研究所によって最初に作成された有限要素コードで前述のブロッキング ・アプローチを実装する原動力となりました。 ベクトルベース ・ コンピューターが衰退すると、これらのコードはスレッドを使用して、 MPI ランクで要素ブロックを並列に処理するように進化し、 ブロッキング
はさまざまなキャッシュ ・アーキテクチャー向けにチューニングする課題として残されました。

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

34

3A

従来の AoS アプローチ

3

ブロック化された配列のベクトル化の例

3B

ブロック化された SoA アプローチ

ここで紹介する例は、 従来の AoS とブロッキング SoA アプローチの基本的な特徴とパフォーマンスを示します。
一連の行列乗算は、 モデルの各要素の配列を更新します。 1 要素の場合、 この例の行列 Be、 De、 Ke のサイズはそれぞれ 6x60、 6x6、 60x60 (すべて倍精度で密行列) です。 図 2B は、 ブロック格納法を示しています。 ここで、 大きな配列は、 Fortran 派生型の割付けコンポーネントです。 異なる要素型と行列サイズを持つモデルでは、
WARP3D は同じ型のすべての要素でホモジニアスなブロックを作成します。 Ke の更新は次のように行われます :Ke ← Ke + transpose(Be)DeBe。 フリンジの各種シミュレーションでは、 この更新が 3 億回～ 10 億回行われます (De Be も更新ごとに変わります)。 この例では、 De と Ke は対称であるため、 下三角のみ計算されます。

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

35

図 3A は、 従来の AoS アプローチに不可欠なコードです。 計算の外側のループは、 対称、 非対称など、 呼び出
されるサブルーチンの異なるバージョンでモデルのすべての要素をシーケンシャルに循環し、 サブルーチンの内側のループは、 1 つの要素行列の小さな次元を循環します。 19 行目の Fortran 組込み関数 matmul は、 Ke の下三角の最終更新を計算するため、 比較的小さな要素配列をループして最初の行列積を実行します。 19 行目に追加された最適化レポートのループ交換に関する詳細なメッセージから、 コンパイラーは、 23 ～ 25 行目の k=1,6の内部ループをアンロールして、 matmul を同等のソースコードに置換してから、 コンパイルしていることが分かります。 [編集者注 : コンパイラーの最適化レポートの生成と解釈に関するアドバイスは、 The Parallel Universe 27号の 「インテル® AVX-512 で向上したベクトル化のパフォーマンス」 を参照してください。 ]図 3B のブロック化された SoA アプローチのコードは、 次の順序で計算ループを実行します。
1. すべてのブロック (ここでは示していません)
2. 1 つの要素行列の次元
3. ブロックの各要素 (スパン) を処理する最内ループ

10 ～ 28 行目の最初のループは、 指定されたワークスペースでブロックのすべての要素について db = DeBe の積を計算します。 単純な実装では、4 レベルのループ構造になります。 ここでは、2 つの最内ループを手動でアンロー
ルして、 長い i=1,span ループをベクトル化するようにコンパイラーに強制します。 その他の手法は、 これらのルー
プの実行時間を増加させます。 コンパイラーは、 各ループの反復回数を認識できないため、 ループの並べ替えの効
果は限定されます。30 ～ 42 行目の 2 つ目のループは、Ke ← Ke + transpose(Be)db の更新を実行します。ここで、utsz=1820 はインデックス・ベクトル icp を使用して要素の下三角形をブロック Ke の列にマップします。 ここでも、最内ループを手動でアンロールして i=1,span をベクトル化しています。
このルーチンの 2 つのループ (10 ～ 28 行目と 30 ～ 42 行目) は、 ベクトル化のユニットストライドの配列参照と(span) 長さ設定のみを含みます。 これは、 WARP3D コード全体にわたる特徴です。 これらは一般に WARP3Dの要素レベルの処理では最も時間のかかるループです。 コンパイラーによる最適化とプロセッサー性能の進化に伴って、 長年、 ループと配列の構成は何度も見直されてきました。

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

36

図 4 は、 それぞれのアプローチをシングルスレッドで実行した場合の相対実行パフォーマンスです。 AoS アプ
ローチでは、 ユニット値を指定しています。 括弧で囲まれた数値は、 計算ルーチン内の配列のサイズを示します。
次のコンパイラー ・ オプションを使用しました : ifort (17.0.2) -O3 -xHOST -align array64byte -ftz。 テストには、 デュアル インテル® Xeon® プロセッサー E5-2698 v3 (インテル ® AVX2 対応) 搭載のコンピューターを使用し、 テスト中ほかのユーザー ・ ソフトウェアは実行していません。 このプロセッサーのキャッシュサイズは、 L1 =32KB/ コア、 L2 = 256KB/ コア、 L3 = 40MB 共有です。 ドライバーコードと計算ルーチンは、 インライン展開されないように個別のファイルに記述しました。 実行時間には、計算ルーチンの呼び出しは含まれますが、ドライバーのセットアップは含まれません。 ドライバープログラムは、 AoS と SoA テスト用の配列を割り当てます。 呼び出
しごとに、 ドライバーはランダムに選択されたセットを計算ルーチンに渡します。 すべてのケースでは、 3200 万要素を処理します。 複数回実行し、 それぞれ 2 ～ 4 分で完了したことから、 評価に使用した CPU には 1 ～ 2%の変動性があることが分かります。

4

両アプローチを 1 スレッドで実行した場合の相対実行パフォーマンス

AoS アプローチには調整可能なパラメーターがないため、1 つの結果で十分でした。 SoA アプローチでは、各ケースで処理される要素数が同じになるようにブロック数を調整しているため、 ブロックごとの要素数 (span) が異なります。 SoA の結果は、 想定どおり、 ベクトル処理の幅と L1、 L2、 L3 キャッシュ効率の相互作用によってブロッ
クサイズが大きく影響することを示しています。 ブロックサイズが 64 および 32 要素の場合、 実行時間は最小となり、 AoS 時間の 37% になります。 16 要素では実行時間は増加します。 すべてのブロックサイズで、 配列は L3
キャッシュに収まります。 より小さな AoS の 1 要素の配列は、 L2 データキャッシュに収まります。

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

37

図 5 は、インテル® Advisor 2017 のルーフライン解析の実行結果です。 比較のため、1 つのプロット上に主要なケースの結果を手動で追加しています。両方の軸の目盛りに注意してください。グラフィカルなツールを備えたインテル®
Advisor のルーフライン解析は、 大規模なコードの主要なループのパフォーマンスを評価するのに便利なメカニズ
ムを提供します (右上にメニューがあります)。 記号の上にマウスポインターを移動すると、ポップアップが開き、ソー
スコード中のループの場所、 GFLOPS、 L1 キャッシュの 1 バイトあたりの浮動小数点演算数が表示されます。 記
号をクリックすると、 ループのソースコードとパフォーマンスに関する追加情報 (例えば、 ループのピールループやリマインダー ・ ループが実行されたかどうかなど) が表示されます。

5

ルーフライン解析の結果

33 ～ 41 行目の Ke 更新の内部ループで、 ブロックサイズ (span) = 64 の最高パフォーマンス 8.08 GFLOPS は、
L2 キャッシュラインのルーフライン上にありますが、 このループのカーネルである FMA (Fused-Multiply-Add)
ベクトル命令のピークレートよりかなり下にあります。 11 ～ 27 行目の DeBe 計算の内部ループは、 ブロックサイズを 1024 → 128 に減らすとパフォーマンスが 3.7 倍と驚異的に向上しますが、 それよりも小さなブロックサイズではさらなるパフォーマンス ・ ゲインは見込めません。 33 ～ 41 行目の最も長いループは、 ブロックサイズを1024 → 64 に減らすことでパフォーマンスが 2 倍に向上します。

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

38

実行時間の結果 (図 4) から予測されるように、 AoS の GFLOPS とキャッシュ効率 と は、 ブロック化されたSoA を下回ります。 ルーチンのコードを直接 ek = ek + matmul(transpose(b), matmul(d,b)) に置換することで、
図 3A のバージョンよりも実行時間が 30% 向上します。
ルーフライン上の倍精度 FMA ピークの 52.6 GFLOPS に対し、 最高パフォーマンスが 8.08 GFLOPS であるのは、 メモリーアクセスあたりの浮動小数点演算数が小さいためです。 これは、 有限要素法に固有の要素レベルの計算のよく知られた特徴です。 12 の倍精度演算 (6 つの加算と 6 つの乗算) と 13 の倍精度配列の参照を含む
33 ～ 41 行目の主要な内部ループについて考えてみます。 バイトあたりの計算負荷は 12/(13*8) = 0.11 で、 ルー
フライン解析の FLOP/L1- バイトと同じです。 この値は、 ブロックサイズに関係なく一定です。 参考として、 図には
WARP3D の方程式の解の計算中 (シングルスレッド) にルーフライン解析によって表示された、 インテル® MKL のBLAS の最高のパフォーマンスのルーチンも示されています。
ベンチマークに関して、 いくつかの要点をまとめました。
•• コード解析リストの [Roofline (ルーフライン)] タブ : 33 ～ 41 行目のループの唯一の 「特徴」 は FMA で、 ベクトル化の効率は 81% (スカラーの 3.24 倍)、 ベクトル幅 = 4 つの倍精度 (インテル® AVX2) です。 さらに、 メモリー・アクセス ・ パターンの [Roofline (ルーフライン)] タブから、 ルーチンの 2 つの内部ループはすべての配列にストラ
イド -1 でアクセスしていることが分かります。
•• メモリー ・アライメント。 コンパイルでは、 –align array64byte オプションを使用します。 これは、 インテル® AVX512 命令をサポートするプロセッサー上で最高のパフォーマンスを達成するために必要です。 ここで使用したインテル ®
AVX2 対応プロセッサーでは 32 バイト境界のアライメントで十分です。 driver.f と routines.f は個別にコンパイルされるため、 コンパイラーはサブルーチン bdbtSoA の仮配列引数の実際のアライメントを把握していません。 Fortran コ
ンテキストでこれらの調整可能な配列は、 配列要素がメモリー上で連続していることをコンパイラーに保証しますが、必ずしも特定の境界でアライメントされているとは限りません。 予想どおり、 アノテーション付きのソースリストは、 す
べての配列についてアライメントされていないアクセスを示しています。
ソースコードで 2 つの内部ループの前に !DIR$ ASSUME_ALIGNED b(1,1,1):64, d(1,1,1):64, ... または !DIR$
VECTOR ALIGNED ディレクティブを追加してみたところ、目立ったパフォーマンスの向上は見られませんでした。アノテーション付きのソースリストは、すべての配列についてアライメントされたアクセスを示しています。
その理由は、インテル® Advisor のメッセージから分かります。アクセスがアライメントされるまで最初のいくつかのループ反復を別に実行するピールループとリマインダー・ループが、ここではソースコード・ディレクティブなしでも実行されません。driver.f のコンパイルで –align array64byte オプションを指定することで、実行時にループに入る前の配列のアライメントが、すべてのケースで 64 バイトになります。
•• ユニットストライド。 簡単なテストによって、 パフォーマンスに対 するストライド -1 の配列参照の (少なくともこのプロセッサーにおける) 重要性を示すことが できます。 配列 ek_symm(span,utsz) の 代 わりに ek_symm(utsz,span) を使用し、 34 行目の ek_symm(i,j) を ek_symm( j,i) に変更すると、 パフォーマンスが 8.08
GFLOPS から 2.39 GFLOPS へ低下します。

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

39

まとめ
ベクトル化は、 配列を利用する計算コードにスピードアップの可能性をもたらします。 ベクトル化によるスピードアッ
プは、 スレッドとクラスターでの分散実行を利用する高レベルの並列計算によって得られるパフォーマンス向上を増幅させます。 ベクトル化の主な特徴として、 プロセッサー ・ キャッシュと命令に応じてチューニング可能な配列サイズと、 内部ループ内のストライド -1 アクセスがあります。
ベクトル化によりパフォーマンスを向上する重要性は、 新しいプロセッサーにおいて、 頭打ちになっているクロック
レートやスレッドのスケーラビリティーに代わり、 ハードウェアがベクトルレジスターの数を 8 つの倍精度 (そしてそれ以上) に拡張することで、 高まり続けるでしょう。
インテル® Advisor、 特に新しいルーフライン解析機能は、 さまざまなレベルの開発者に、 関連のあるパフォーマ
ンス情報と推奨事項を使いやすい GUI で提供します。

謝辞
WARP3D が研究者にとって有用なコードになるよう尽力してくれた、 多数の教え子である大学院生、 博士課程修了
者、 そして世界中の協力者に厚く感謝します。 協力者とスポンサーの一覧は、 warp3d.net (英語) を参照してください。 コード ・ パフォーマンスを向上する最近の取り組みは、 Kevin Manalo 博士と Karen Tomko 博士の協力、 そして Ohio Supercomputer Center のインテル® Parallel Computing Center のサポートの下に実施されました。

参考資料「インテル® Advisor のルーフライン解析」、 The Parallel Universe 27 号、 2017 年。
「インテル® AVX-512 で向上したベクトル化のパフォーマンス」、 The Parallel Universe 27 号、 2017 年。
「Fortran の明示的なベクトル ・ プログラミング」 (英語)、 Martyn Corden (Intel)、 2016 年 1 月。
「ベクトル化によるパフォーマンスの向上」、 David M.、 2016 年 9 月。

著者紹介
Robert H. Dodds Jr. 博士は、 全米技術アカデミー (NAE) 会員であり、 イリノイ大学アーバナ ・ シャンペーン校の土木工学の M.T. Geoffrey Yeh Chair (名誉教授) です。 現在は、 テネシー大学ノックスビル校の土木工学科の研究教授です。

インテル® Parallel Studio XE のベクトル化ツールを評価する ›コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

40

クラウドおよびエッジ ・アプリケーション
向けの高速データ圧縮コードのビルド
インテル® IPP を利用した圧縮の最適化
Chao Yu インテル コーポレーション ソフトウェア ・ テクニカル ・ コンサルティング ・ エンジニア
Sergey Khlystov インテル コーポレーション シニア ・ ソフトウェア ・ エンジニア

データを効率良く圧縮 / 展開する方法を見つけることはこれまで以上に重要になっています。 圧縮されたデータはサイズが小さく、 転送時間とネットワーク帯域幅も少なくて済みます。 クラウド ・ サービス ・ コードでは、 効率良い
圧縮はストレージコストの削減につながります。 モバイルおよびクライアント ・アプリケーションでは、 ハイパフォー
マンスの圧縮は通信効率を向上し、 ユーザー ・エクスペリエンスを改善します。
しかし、 圧縮 / 展開はプロセッサー ・ リソースを消費します。 特に、 データを多用するアプリケーションでは、 シス
テム全体のパフォーマンスが低下する可能性があります。 そのため、 圧縮アルゴリズムの最適化された実装は、 シ
ステム ・ パフォーマンスへの影響を最小限に抑える上で重要な役割を果たします。 インテル® インテグレーテッド ・
パフォーマンス ・ プリミティブ (インテル® IPP) は、 可逆データ圧縮を含むさまざまなドメイン向けに高度に最適コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

41

化された関数群のライブラリーです。 この記事では、 これらの関数と最新の改善点について述べます。 これらの関数のパフォーマンスを評価し、 最高のパフォーマンスを達成する最適化方法を説明します。 また、 ワークロードの特徴に基づいてアプリケーションに適した圧縮アルゴリズムを決定する方法を示します。

インテル® IPP のデータ圧縮関数
インテル® IPP のデータ圧縮ドメインは、 BZIP2、 ZLIB、 LZO、 および新しい LZ4 関数 (インテル® IPP 2018
Beta Update 1 で追加) を含む、 一般的なデータ圧縮アルゴリズムの最適化された実装を提供します。 これらの実装は、 オリジナルの圧縮コードの 「ドロップイン」 代替品であり、 オリジナルのデータ圧縮コードからインテル®
IPP の最適化されたコードへ簡単に移行できます。
これらのデータ圧縮アルゴリズムは、 多くのアプリケーションで基本関数として使用されているため、 さまざまなア
プリケーションでインテル ® IPP の恩恵を受けられます。 典型的な例として、 インテル® IPP の ZLIB 圧縮が挙げられます。 ZLIB は、 さまざまなファイルアーカイブ (gzip、 WinZip*、 PKZIP* など)、 ポータブル ・ ネットワーク ・ グ
ラフィックス (PNG) ライブラリー、 ネットワーク ・プロトコル、 いくつかの Java* 圧縮クラスで使用されている基本
的な圧縮手法です。 図 1 は、 これらのアプリケーションでインテル® IPP の最適化された ZLIB を利用する方法を示しています。 インテル® IPP は完全に互換性がある API を提供します。 アプリケーションは、 インテル® IPP のZLIB ライブラリーと再リンクするだけです。 アプリケーションが ZLIB をダイナミック ・ ライブラリーとして使用している場合は、インテル® IPP でビルドした新しいダイナミック ZLIB ライブラリーに簡単に切り替えることができます。
その場合、 アプリケーションの再リンクは不要です。

1

インテル® IPP はドロップインの最適化された ZLIB 関数を提供

最近のリリースでは、 インテル® IPP のデータ圧縮ドメインのいくつかの機能が拡張され、 圧縮パフォーマンスが向上しました。
•• LZ4 データ圧縮のサポートは、 インテル® IPP 2018 で追加されました。
•• LZO 圧縮パフォーマンスが 20 ～ 50% 向上。 LZO 展開にレベル 999 サポートが追加されました。
•• 新しい最速 ZLIB データ圧縮モード。 ZLIB レベル 1 と比較してパフォーマンスを 2.3 倍向上できます。
•• トレーニング済みハフマンテーブル。 ZLIB 圧縮向けのこのテーブルは、 最速モードでの圧縮率を改善します。

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

42

インテル® IPP のデータ圧縮の最適化
インテル ® IPP のデータ圧縮は、 どのようにして最適化され、 優れたパフォーマンスを達成するのでしょうか ?
インテル® IPP は、いくつかの異なる手法を使用してデータ圧縮機能を最適化します。 強いデータ依存性により、現代のプラットフォームにおけるデータ圧縮アルゴリズムの最適化は困難です (アルゴリズムの振る舞いは入力
データに依存します)。 基本的に、 新しい CPU 命令のみがこれらのアルゴリズムをスピードアップすることができます。 SIMD (Single Instruction Multiple Data) 命令は、 主にパターン検索など、 一部のケースでのみ利用できます。
インテル® IPP のデータ圧縮パフォーマンスの最適化は、 異なる手法を用いて異なるレベルで行われます。
•• アルゴリズムの最適化•• データの最適化•• 新しい CPU 命令•• インテル® IPP のデータ圧縮パフォーマンス

アルゴリズムの最適化
最も高いレベルでのアルゴリズムの最適化は、 最も大きな利点をもたらします。 インテル® IPP のデータ圧縮アルゴ
リズムは、 効率良く入力データを処理し、 出力を生成するため、 ゼロから実装されています。 例えば、 入力データ処理の適切な開始条件を選択することで、 プロセスの初期段階からパフォーマンス ・ ゲインを得ることができます。
入力データからパターンを検索する処理について考えてみます。 最小一致長を 2 ～ 3 バイトに設定すると、 より多くの一致が検出され、 優れた圧縮率が得られますが、 入力データ処理にかかる時間が大幅に増えます。 そのため、圧縮率と圧縮パフォーマンスのバランスが良い最小一致長にすべきです。これは統計的実験の結果に基づいて、コードで条件チェックと分岐を綿密に調整することで達成できます。 すべてのケースにおいて、 最も可能性の高い条件をコードの先頭に配置すると効率的です。 そうすることで、 可能性の低い処理に時間をかけずに済みます。

データの最適化
内部データのレイアウトとサイズを綿密に計画することもパフォーマンスの向上につながります。 データを適切にアライメントすることで、 データの読み書きにかかる CPU クロック数を節約できます。 ほとんどの CPU では、 アライ
メントされたデータのほうが、 アライメントされていないデータよりも高速に読み書きすることができます。 これは
特に 16 ビットを超えるデータ要素に対してメモリー操作を実行する場合に当てはまります。 最適化に影響するもう 1 つの要因はデータサイズです。 内部データ構造 (配列、テーブル、リスト) が小さければ、CPU データキャッシュの再利用率が高まり、 全体のパフォーマンスが向上します。

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

43

新しい CPU 命令
インテル® ストリーミング SIMD 拡張命令 4.2 (インテル® SSE4.2) アーキテクチャーでは、 データ圧縮に使用できるいくつかの命令が追加されました。 インテル® アドバンスト ・ ベクトル ・エクステンション 2 (インテル® AVX2) 命
令セットでは、 さらに多くの命令が追加されました。 CRC32 命令は、 データの整合性を確認するため、 入力デー
タのチェックサムの計算に使用できます。 これは、多くのデータ圧縮規格において重要な部分です。 CRC32 命令は、
圧縮アルゴリズムの別の重要な部分である、ハッシュ関数の実装にも使用できます。ビット操作命令 (BMI) もパターン一致関数の高速化に役立ちます。さらに、32/64/128/256 ビット単位でデータの読み書きをすることで、メモリー・バス ・ サイクルが軽減され、 パフォーマンスの向上につながります。

インテル® IPP のデータ圧縮パフォーマンス
インテル® IPP 関数には、 複数のコードパスが含まれており、 各パスは特定の世代のインテル® プロセッサーまたは互換プロセッサー向けに最適化されています。 また、新しいプロセッサーがリリースされる前に、そのプロセッサー
向けに最適化されたコードパスが追加されるため、最新のインテル® IPP にリンクするだけで、最新のプロセッサー・
アーキテクチャーの利点が得られます。
図 2 は、 インテル® IPP の ZLIB 圧縮 / 展開ライブラリーのパフォーマンスを示しています。 オープンソースの ZLIB
コードと比較して、 インテル® IPP の ZLIB 実装は、 圧縮レベルに応じて 1.3 ～ 3.3 倍のパフォーマンスを達成しています。 また、 インテル® IPP は、 完全に互換性のある API と圧縮結果を提供します。

システム構成 – ソフトウェア : インテル® IPP 2017、インテル® C++ コンパイラー 16.0。 ハードウェア : インテル® Core™ i7-6700K プロセッ
サー、 8MB キャッシュ、 4.20GHz、16GB RAM、Windows Server* 2012 R2。 性能に関するテストに使用されるソフトウェアとワークロー
ドは、 性能がインテル ® マイクロプロセッサー用に最適化されていることがあります。

2

インテル® IPP の ZLIB 圧縮/展開ライブラリーのパフォーマンス

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

44

アプリケーションに適した圧縮アルゴリズムの選択
データ圧縮では、 圧縮パフォーマンスと圧縮率のトレードオフを考慮する必要があるため、 すべてのアプリケーションに最適な圧縮アルゴリズムというものはありません。 例えば、BZIP2 アルゴリズムは圧縮効率に優れていますが、複雑なため圧縮 / 展開の両方に多くの CPU 時間を必要とします。
図 3 は、 一般的なインテル® IPP 関数の圧縮パフォーマンスと圧縮率を要約したものです。 これらのアルゴリズムの中では LZ4 が最も速く、 標準的な圧縮データでは BZIP2 よりも 20 倍高速です。 ただし、 圧縮率は BZIP が最も優れています。 ZLIB はパフォーマンスと効率のバランスが良いため、多くのファイルアーカイブ、圧縮ネットワー
ク ・プロトコル、 ファイルシステム、 可逆画像形式で採用されています。

3インテル® IPP の一般的な関数と圧縮率

ユーザー ・アプリケーションに適した圧縮アルゴリズムの決定には、 通常、 多くの要因が関連します。
•• 圧縮パフォーマンス : アプリケーションの要件を満たす必要があります。
•• 圧縮率•• 圧縮レイテンシー : リアルタイム ・アプリケーションでは特に重要です。
•• メモリー ・ フットプリント : 組込みターゲット ・アプリケーションの要件を満たす必要があります。
•• 標準の圧縮法との適合性 : 標準のアーカイブ ・ユーティリティーでデータを展開できるようにします。
•• その他の要因 (アプリケーションで必要とされる場合)

特定のアプリケーションの圧縮アルゴリズムを決定するには、 これらすべての要因のバランスに加えて、 ワークロードの特徴や要件を考慮する必要があります。 すべての状況に最適な圧縮法はありません。

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

45

典型的なデータ圧縮の使用例について考えてみます。 サーバーからクライアント ・アプリケーションへファイル転送が必要なダウンロードでは、 最良のパフォーマンスを達成するため、 クライアントに転送する前に、 サーバー側で可逆データ圧縮を実行します。 この場合、 クライアント・アプリケーションはネットワーク経由でデータをダウンロー
ドした後で、それを展開する必要があります。全体のパフォーマンスは、転送と展開のパフォーマンスに依存するため、ワークロードとネットワークの特徴を慎重に検討する必要があります。 BZIP2 のような一部の高圧縮アルゴリズム
は、 データ転送を軽減します。 一方、 BZIP2 の展開は、 ほかの圧縮法よりも処理に時間がかかります。
図 4 は、 異なるネットワーク速度におけるインテル® IPP の一般的な圧縮アルゴリズムの全体パフォーマンスを示しています。 テストには、インテル® Core™ i7-6700K プロセッサーを使用しました。 コードを低帯域幅のネットワー
ク (例 : 1Mbps) で実行する場合、 圧縮アルゴリズムには、 転送データと転送時間の軽減のため、 高い圧縮率を達成することが求められます。 テストシナリオでは、 非圧縮転送と比較して、 インテル® IPP の BZIP2 が最良のパフォーマンス (約 2.7 倍のスピードアップ) を達成しました。 しかし、高帯域幅のネットワーク (例 : 512Mbps) でデー
タを転送する場合は、 圧縮時間と転送時間のバランスが良い LZ4 の全体パフォーマンスが最良となりました。

システム構成 – ソフトウェア : インテル® IPP 2018 BetaUpdate 1、 インテル® C++ コンパイラー 16.0。 ハードウェア : インテル® Core™
i7-6700K プロセッサー、 8MB キャッシュ、 4.20GHz、 16GB RAM、 Windows Server* 2012 R2。 性能に関するテストに使用されるソ
フトウェアとワークロードは、 性能がインテル ® マイクロプロセッサー用に最適化されていることがあります。

4

圧縮あり/なしのデータ転送

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

46

最適化されたデータ圧縮
今日のデータセンターとエッジ接続デバイスでは、 データの格納と管理の重要性が高まりつつあります。 インテル®
IPP は、 高度に最適化された使いやすいデータ圧縮関数を提供します。 新しい CPU 命令と改善された実装アルゴリズムにより、 広範なアプリケーションとアーキテクチャーにおいてデータ圧縮アルゴリズムがパフォーマンスを大幅に向上できるようにします。 インテル® IPP は、 さまざまなアプリケーションのニーズに対応するため、 一般的な可逆圧縮アルゴリズムも提供します。

BLOG HIGHLIGHTS
インテル® Xeon Phi™ プロセッサーでの MPI-3 共有メモリーの使用
LOC Q NGUYEN (INTEL) ›MPI-3 共有メモリーは、 メッセージ ・ パッシング ・ インターフェイス (MPI) バージョン 3.0 で追加された機能です。
インテル ® MPI ライブラリー 5.0.2 以降で実装されています。 MPI-3 共有メモリーは、 複数の MPI プロセスが計算ノードの共有メモリーに割り当て / アクセスできるようにします。 複数の MPI プロセスが大きなローカルデータを扱うアプリケーションでは、 この機能によりメモリー ・フットプリントを軽減し、 パフォーマンスを大幅に向上することができます。
このホワイトペーパーでは、 MPI-3 共有メモリー機能、 対応する API、 およびインテル® Xeon Phi™ プロセッサー
での MPI-3 共有メモリーの使用方法を示すサンプルプログラムを紹介します。
この記事の続きはこちら (英語) でご覧になれます。

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

エッジ
の効いた

コードの作成スケーラブルで、移植性に優れた、将来にも通用するコードを作成しよう
インテル® Fortran および C++ コンパイラーは、作業中の開発環境でコードを最適化および高速化します。

将来のコードを今から作成しよう
C++ のダウンロード›
Fortran のダウンロード›

コンパイラーの最適化に関する詳細は、最適化に関する注意事項を参照してください。
Intel、インテル、Intel ロゴは、アメリカ合衆国および / またはその他の国における Intel Corporation の商標です。
* その他の社名、製品名などは、一般に各社の表示、商標または登録商標です。
© Intel Corporation.

48

インテル® C++ コンパイラーによる
MySQL* の最適化
LeCloud による MySQL* を利用したピークサービス向上の取り組み

Huixiang Tao LeCloud Computing Co., Ltd. データベース ・ チーフ ・ アーキテクト
Ying Hu インテル コーポレーション ソフトウェア ・ テクニカル ・ コンサルティング ・ エンジニア
Ming Gao インテル コーポレーション インダストリー ・ テクニカル ・ スペシャリスト

LeCloud ( 英語 ) は、 60 の国と地域にわたって独自のコンテンツ配信ネットワーク (CDN) ノードを展開する主要ビデオ ・ クラウド ・ サービス ・プロバイダーです。 LeCloud の利用可能帯域幅は、 クラウドオンデマンド、 コンテンツ共有、 商業イベントの配布とライブ配信、 バーチャル・リアリティー ( VR) などのクラウドサービスに対応するため、20Tbps にも上ります。 LeCloud プラットフォームは、 年間 100 万を超えるライブイベント、 毎日何億ものデバイ
スアクセス、毎秒数百万の同時ユーザーをサポートしています。 LeCloud のハイパフォーマンスな公共データベース・
サービスに対する需要は非常に高く、 LeCloud では人気のあるオープンソース ・ データベース MySQL* をクラウドサービスの基盤として採用しています。

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

49

LeCloud の主要な課題の 1 つは、 MySQL* データベースのパフォーマンスを最適化することです。 これは、 多くのデータベース管理者 (DBA)、 オペレーター、 保守担当の IT 開発者にとっても重要な課題です。 以下は、 パフォー
マンスに関する懸念事項です。
•• 1 秒あたりのクエリー数 (QPS)•• 1 秒あたりのトランザクション数 ( TPS)•• クエリー応答時間

この記事では、 インテル® C++ コンパイラーとそのプロシージャー間の最適化 (IPO) 機能を利用して、 LeCloud がMySQL* を最適化した方法を紹介します。 ここでは、 コードを全く変更せずに、 MySQL* ソースコードをコンパイ
ルしてパフォーマンスを評価してみました。 その結果、 いくつかのテストシナリオで MySQL* ソースコードに対してインテル® C++ コンパイラーの最適化を適用したところ、 パフォーマンスが 5 ～ 35% 向上し、 開発者に MySQL*のパフォーマンスを改善するための新たな道が開けました。

インテル® C++ コンパイラー
インテル® Parallel Studio XE のコンポーネントであるインテル® C++ コンパイラーは、 パフォーマンスを最大限に引き出すため最新の命令セットとアーキテクチャー機能を利用する、 C/C++ 最適化コンパイラーです。 インテル®
コンパイラーの開発チームは、 インテル® アーキテクチャーを熟知しているため、 GNU* GCC や Microsoft* Visual
C++* などのコンパイラーよりも、 新しい SIMD 命令やキャッシュ構造などのインテル® プロセッサーの機能に特化した効率良い最適化を行うことができます。 以下は、 このケーススタディーで利用した最適化手法の一部です。
•• 自動ベクトル化•• ガイド付き自動並列化 (GAP)•• プロシージャー間の最適化 (IPO)•• プロファイルに基づく最適化 (PGO)

インテル® コンパイラーは、 ユーザーがインテル® アーキテクチャー ・ ベースのプラットフォームの利点を最大限に引き出せるように支援します。

自動ベクトル化
インテル ® コンパイラーの自動ベクトル化機能は、 インテル ® ストリーミング SIMD 拡張命令 (インテル® SSE )、インテル ® SSE2、 インテル ® SSE3、 インテル ® SSE4、 インテル ® ストリーミング SIMD 拡張命令 3 補足
命令 ( インテル ® SSSE3)、 インテル ® アドバンスト ・ ベクトル ・ エクステンション (インテル ® AVX )、 インテル ®
AVX2、 インテル ® AVX512 命令セットの SIMD 命令を自動的に使用します。 プログラム中の並列に実行可能な処理を検出し、 シーケンシャル処理を並列処理に変換します。 例えば、 データ型に応じて、 最大 16 要素を処理するシーケンシャルな SIMD 命令を 1 つの並列処理に変換します。 インテル ® コンパイラーは、 このケース
スタディーで使用したインテル® Xeon® プロセッサー E5-2699 v4 を含む最新のプロセッサー上でコンパイラー
が効率良くベクトル命令を生成できるように、 自動ベクトル化のヒントもサポートしています。

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

50

ガイド付き自動並列化 (GAP)
インテル® C++ コンパイラーのガイド付き自動並列化機能は、 シーケンシャル ・アプリケーションのパフォーマンス
を向上できるように、 コンパイラーの機能を利用して、 自動ベクトル化、 自動並列化、 データ処理の効率を改善するための変更をアドバイスします。

プロシージャー間の最適化 (IPO)
インテル® C++ コンパイラーのプロシージャー間の最適化機能は、 複数のステップから成る自動プロセスで、 コン
パイラーはコードを解析して、 ソースファイル内または複数のソースファイルにまたがるプロシージャー間の最適化(つまり、 個別のプログラム ・ サブユニットを超えた最適化) を見つけます。 IPO については、 このケーススタディーの主要コンポーネントであるため、 後で詳しく述べます。

プロファイルに基づく最適化 (PGO)
インテル® C++ コンパイラーのプロファイルに基づく最適化機能では、 コードを実行中にコンパイラーがコードを解析して、 再コンパイル時にこのプロファイル情報を利用します。 これにより、 コードサイズが縮小し、 分岐予測ミスが減り、 命令キャッシュの問題を最小限に抑えるためコードレイアウトが見直され、 アプリケーションのパフォーマンスが向上します。

MySQL* の最適化
IPO によるコンパイル
IPO は、 インテル® C++ コンパイラーの主要な最適化機能です。 シングルソースとマルチソースの両方のファイルに基づくコードのプロファイルとスタティック ・ トポロジー解析を行い、 良く使用される小さな関数と中程度の関数を多く含むプログラムでは、 インライン展開、 定数の伝搬、 不要な関数の排除などの特定の最適化を行います。
図 1 に IPO プロセスを示します。
IPO オプションを指定してソースコードをコンパイルすると、 単一ファイルのコンパイルでは、 コンパイラーは現在のソースファイル内で定義されているプロシージャーへの呼び出しをインライン展開します。複数ファイルの IPO では、
インライン展開プラグマまたは属性 (GNU* C/C++) でマークされた関数やクラス宣言にボディーが含まれる C++
クラスメンバー関数など、 複数ソースファイルに従って一部のインライン展開が行われる可能性があります。 IPO オ
プションを指定して各ソースファイルをコンパイルした後、 コンパイラーは疑似オブジェクト ・ファイルにソースコードの中間表現を格納します。
IPO オプションを指定してリンクすると、 コンパイラーによってすべての疑似オブジェクト ・ファイルの IPO が実行されます。 解析処理中、 コンパイラーは擬似ファイル、 オブジェクト ・ファイル、 ライブラリー ・ファイルにあるすべての中間表現を読み取り、 すべての参照が解決されているか、 およびシンボルが擬似オブジェクト ・ファイルで定義されているかどうかを判断します。 擬似オブジェクト ・ファイルにあるデータと関数の中間表現に含まれているシンボ
ルは、 プログラム全体の解析の結果に基づく操作の対象候補です。

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

51

ソースファイル

1

IPO コンパイル

IPO コンパイルプロセス

IL 情報を含む.o ファイル

IPO によるリンク

実行ファイルインテル® コンパイラーによる MySQL* のビルド
このケーススタディーでは、テスト実施時に最新の正式バージョンであった MySQL* (v5.6.27) を使用しています。
このセクションでは、 Linux* 上でインテル® C++ コンパイラーを使用して MySQL* をコンパイルする方法を示します。
•• MySQL* インストール ・ パッケージをダウンロードします。
wget http://downloads.mysql.com/archives/get/file/mysql-5.6.27.tar.gz
tar –zxvf mysql-5.6.27.tar.gz•• インテル® C++ コンパイラーを使用して MySQL* をコンパイルします (図 2)。
1. Cmake をインストールします。
yum -y install wget make cmake gcc gcc-c++ autoconf automake zlib* libxml2* ncurses-devel
libmcrypt* libtool‑ltdl‑devel*
2. インテル® C++ コンパイラーを使用して MySQL* をコンパイルします。 CC に icc を、 CXX に icpc を設定し、 –ipo オプションを指定して IPO を有効にします。

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

52

2インテル® C++ コンパイラーによる MySQL* のビルド•• MySQL* 権限システムテーブルを作成します。
cd /usr/local/mysql-5.6.27-icc
groupadd mysql
useradd -M -g mysql mysql -s /sbin/nologin ;chown -R mysql .
chgrp -R mysql .
./scripts/mysql_install_db --user=mysql --collation-server=utf8_general_ci

パフォーマンス ・ テスト
このテストの目的は、 GNU* コンパイラーでビルドした MySQL* とインテル® コンパイラーでビルドした MySQL* のパフォーマンスを比較することです。 オンライン ・ トランザクション処理 (OLTP) のパフォーマンス ・メトリックには、1 秒あたりのクエリー数 (QPS) と応答時間 (RT) が含まれます。 テストには、 Sysbench* (v0.4.12) を使用しました。 Sysbench* は、 データベースのパフォーマンスを評価する際によく使用される、 モジュール形式のクロスプラッ
トフォームのマルチスレッド ・ ベンチマーク ・ ツールです。 表 1 と表 2 はテストに使用したシステム構成です。

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

53

表 1. ハードウェア構成

ハードウェア構成

サーバー

Dell* PowerEdge* R730xd

CPU

インテル® Xeon® プロセッサー E5-2699 v4 @ 2.20GHz 2

メモリー

128GB

ディスク

インテル® SSD DC S3510 (SATA) 1.50T 1

OS のバージョン

CentOS* 6.6

カーネル

2.6.32-926

インテル® C++
コンパイラーICC-17.0.1

GNU* GCC

4.4.7 20120313 (RedHat* 4.4.7-11)

MySQL*MySQL* 5.6.27

Sysbench*

Sysbench* 0.4.12

表 2. ソフトウェア構成

ソフトウェア構成

テスト手順
同じインテル® SATA SSD ディスク上に 2 つの MySQL* インスタンス (3308 と 3318) をインストールして、 OLTP
テストには Sysbench* を使用しました (図 3)。 テストを実行する前に、 オペレーティング ・ システムのキャッシュを削除して、MySQL* の query_cache を無効にしました。 10 個の MySQL* データベース・テーブルを作成し、各テー
ブルには 100 万件のレコードを格納しました。 OLTP のランダムな読み取りには、 4、 8、 16、 32、 64、 128、および 512 テストスレッドを使用しました。 MySQL* のバッファー ・プール ・ サイズは、 2GB、 8GB、 16GB に設定しました。 各テストを 3 回実行して、 その平均を最終結果としました。

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

54

表 3. テスト手順
インスタンスMySQL* バージョン

コンパイラーエンジン

QueryCache

MySQL* 3308

5.6.27

GCC

Innodb無効

MySQL* 3318

5.6.27

インテル® C++
コンパイラー

Innodb無効

パフォーマンス ・ テスト結果
QPS
インテル® コンパイラーと GNU* コンパイラーでビルドした MySQL* に対する Sysbench* TPS テストの結果を
表 4 と図 3 に示します。 テストケースに応じて、 スレッド数と MySQL* の buffer_pool のサイズは異なります。
全体的に、 インテル® コンパイラーでビルドした MySQL* のほうが QPS が高く、 特にスレッド数が多くなるとその差は歴然です。 インテル® コンパイラーでビルドした MySQL* では、 QPS が 5 ～ 35% 向上しました (図 3)。

表 4.QPS ( 値が大きいほうが良い )スレッド

GCC_2GB

ICC_2GB

GCC_8GB

ICC_8GB

GCC_16GB

ICC_16GB

41036.641184.881406.89

1598.231402.00

1592.23

8

1863.622154.04

2556.772882.072541.712856.2716

3394.35

4013.794949.175444.824915.525468.5932

5639.776625.039036.919599.00

9034.98

9570.54646975.849510.3112796.34

14680.04

12839.79

14662.85

1286975.05

9465.0312410.70

14804.35

12391.96

14744.11

2566859.379367.19

11586.47

14083.09

11574.40

13887.13

5126769.549260.24

10904.25

12290.8910893.18

12310.28

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

55

平均応答時間インテル® コンパイラーと GNU* コンパイラーでビルドした MySQL* に対する Sysbench* 平均応答時間 (RT) テス
トの結果を表 5 と図 4 に示します。 RT はミリ秒単位です。 QPS テストと同様に、 テストケースに応じて、 スレッド数と MySQL* の buffer_pool のサイズは異なります。 ここでも、 インテル® コンパイラーでビルドした MySQL* のほうが優れたパフォーマンスを達成しており、 特にスレッド数が多くなるとその差は顕著です。

表 5. 平均応答時間 (ミリ秒単位、 値が小さいほうが良い )スレッド

GCC_2GB

ICC_2GB

GCC_8GB

ICC_8GB

GCC_16GB

ICC_16GB

4

3.86

3.38

2.84

2.50

2.85

2.51

8

4.29

3.71

3.13

2.77

3.15

2.80

16

4.71

3.98

3.23

2.94

3.25

2.93

32

5.67

4.83

3.54

3.33

3.54

3.34

64

9.17

6.73

5.00

4.36

4.98

4.36

128

18.35

13.52

10.31

8.64

10.33

8.68

256

37.32

27.33

22.09

18.18

22.12

18.45

512

75.63

55.29

46.95

41.65

47.00

41.59

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

56

3インテル® C++ コンパイラーと GNU* GCC でビルドした MySQL* の QPS

4インテル® C++ コンパイラーと GNU* GCC でビルドした MySQL* の応答時間

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

57

まとめ
パフォーマンス目標を達成しようとする DBA、 オペレーター、 開発者にとって、 MySQL* のパフォーマンスを最大化することは不可欠です。 このケーススタディーでは、 インテル® コンパイラーを使用して MySQL* をビルドすることで、 データベースのパフォーマンスを大幅に向上できることを示しました。 インテル® C++ コンパイラーにより、
パフォーマンスが 5 ～ 35% 向上し、 平均では 15% の向上を達成できました。
MySQL* のパフォーマンスには、 MySQL* の設定、 CPU、 SSD を含む多くの要因が影響します。 例えば、 最初はインテル® Xeon® プロセッサー E5-2620 v3 を使用しましたが、 パフォーマンスを向上するためインテル® Xeon®
プロセッサー E5-2699 v4 にアップグレードしました。 このケーススタディーで使用したインテル® SSD DC S3510
シリーズの代わりにインテル® SSD DC P3700 シリーズのような高速な SSD を使用することで、 さらにパフォーマンスを向上できるでしょう。

参考資料
1. インテル® Media Server Studio 製品情報
2. MySQL* Cluster NDB 7.3–7.4 リファレンス ・ ガイド
3. CMake リファレンス ・ ドキュメント (英語 )インテル® C++ コンパイラーを評価する
インテル® Parallel Studio XE に含まれます ›コンパイラーの最適化に関する詳細は、 最適化に関する注意事項を参照してください。

58

インテル® DAAL による R の
線形回帰の高速化
高度に最適化されたオープンソース ・ パッケージを使用してより正確に予測

Steena Monteiro インテル コーポレーション ソフトウェア ・ エンジニア
Shaojuan Zhu インテル コーポレーション テクニカル ・ コンサルティング ・ エンジニア

線形回帰は、 以前に収集した観測情報を利用して結果を予測する古典的な統計アルゴリズムです。 以前に収集したデータを基に予測し、 結果を収益化するビジネスはいくつかあります。 一般的な例としては、 新しい四半期の売上予測や消費パターンに基づく信用リスクの予測などが挙げられます。 インテル® データ ・ アナリティクス ・ アクセ
ラレーション ・ ライブラリー (インテル® DAAL) は、 インテル® プロセッサー向けに最適化されたチューニング済
みのさまざまなマシンラーニング ・アルゴリズムを提供します。 この記事では、 インテル® DAAL のチューニング済
みの線形回帰を利用して、 統計アルゴリズムおよび解析向けのソフトウェア言語である R の線形回帰を高速化します。 予備パフォーマンス分析では、 インテル® DAAL の線形回帰のほうが、 演算強度が高く、 システム利用率が優れています。 インテル® DAAL を R の線形回帰に組み込むことで、 モデルの訓練を最大で 300 倍、 モデルの推論を最大で 373 倍スピードアップできることを示します。

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

59

線形回帰の概要
線形回帰 1 は、 従属変数の値の予測に使用される古典的な統計アルゴリズムです。 単線形回帰は、 次の式に従って 1 つの独立変数 (x) を使用して 1 つの応答 (従属変数 y) を予測します。
y=βx+εここで、 β は回帰線の係数 (傾き)、 ε は切片です。
線形回帰モデルは、 与えられたポイントのセットから、 応答変数の 2 乗誤差が最小になる線を導き出します。 実
際のデータセットには、 ドメインを表す複数の独立変数 (または特徴) が含まれます。 単線形回帰の延長線上にあるのが多重線形回帰で、 多次元の問題空間を表すのに使用されます。 多重線形回帰は、 次のように表されます。
y = α x1 + β x2 + γ x3 + …+ ηxn + ε
ここで、 xi は特徴変数、 α、 β、 γ、 η は対応する係数です。
この記事では、 線形回帰は多重線形回帰を指します。

インテル® DAAL と R の線形回帰の演算強度の解析
アプリケーションの演算強度を計算することで、 アルゴリズムによるシステムの浮動小数点演算能力と帯域幅の利用状況を評価できます。 演算強度 2 は、 アプリケーションが実行した浮動小数点演算数 (Flops) 対アプリ
ケーションの実行中に使用されたバイト数の比率です。 演算強度がシステムの理論値に近い場合、 システムを効率良く利用していることを示します。 インテル® DAAL の予備パフォーマンス解析の結果を踏まえて、 インテル®
Software Development Emulator (インテル® SDE)3 を利用して、 R とインテル® DAAL の線形回帰の演算強度を検証しました。 L1 キャッシュ (32K)、 L2 キャッシュ (256K)、 L3 キャッシュ (20MB) に収まるように調整した 3 つのデータセットの Flops とバイト数を測定しました。 表 1 に、 テストに使用したノードの構成を示します。
テストの結果、 3 つのデータセットで、 インテル® DAAL の線形回帰の演算強度は、 R の線形回帰と比較して 2.4
倍、1.4 倍、1.4 倍になりました。 この結果に後押しされて、インテル® DAAL を使用して R の線形回帰のパフォー
マンスを向上するという、 次の取り組みに着手しました。

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

60

表 1: 開発コード名 Haswell 搭載のノードのシステム構成
コア

ソケットごとに 8 つ

ソケット

1

周波数

2.30GHz (インテル ® ターボ ・ブーストが有効な場合は 3.60GHz)

L1

32K

L2

256K

L3

20480K

表 2: カリフォルニア大学アーバイン校のマシンラーニング ・ リポジトリー 4 からの線形回帰データセット
データセット行(インスタンス )

列
(特徴 )

サイズ
(MB)

予測される応答

Airfoil self-noise( 翼騒音)

1503

5

0.06

音圧レベル

Parkinsons(パーキンソン病 )

5875

19

0.83

臨床医のパーキンソン病の症状スコア

Naval propulsion
plants(海軍の推進プラント)

11934

13

1.24

ガスタービン圧縮機の劣化状態係数

Poker (ポーカー)

1000000

10

80

カードのスーツ

Year prediction
million songs
database(リリースされた年を予測する楽曲
データベース)

51534590371.04

楽曲がリリースされた年の予測

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

61

R の線形回帰 API
R はソフトウェア環境であり、 データ操作、 古典的統計、 グラフィックス、 バイオインフォマティクス、 マシンラーニ
ング向けのアルゴリズムがパッケージ化された言語です。 5 R は lm 関数により線形回帰を提供します。 6 線形回帰
モデルの訓練には lm 関数を、 新しいデータの推論には predict 関数を使用します。

インテル® DAAL の線形回帰
インテル ® DAAL の 2 つの回帰アルゴリズムのうちの 1 つが線形回帰です。 7 インテル ® DAAL の線形回帰は、バッチ、 オンライン、 分散の 3 つのデータ処理モードで実行できます。 バッチモードは、 シリアルモードの実装と考えることができます。 すべてのデータはシーケンシャルに処理されます。 オンラインモードでは、 データが利用可能になると、 アルゴリズムはデータをブロック化して訓練します。 分散モードでは、 インテル ® DAAL の線形回帰を複数の計算ノードで訓練およびテストできます。 インテル ® DAAL は、 線形回帰の訓練とテストに利用できる compute メソッドを Algorithm クラスで提供しています。 R のネイティブコードでは、 線形回帰
をシリアルにのみ実行できます。メモリーに格納できない大きなデータセットは、R では処理できません。ただし、
インテル ® DAAL のオンラインモード (ストリーミング・モードとも呼ばれる) を利用することで、大きなデータセッ
トの処理が可能になります。 この記事では、 線形回帰をバッチモードで使用して R のアルゴリズムを高速化します。 R とインテル ® DAAL の両方で、 線形回帰に QR 分解を使用します。

インテル® DAAL による R の線形回帰の統合
この線形回帰のテストでは、インテル® DAAL の C++ API を使用します。 R の Rcpp8 パッケージを利用することで、R のネイティブコードに C++ 関数を統合できます。 Rcpp は、 R オブジェクトとインテル® DAAL の C++ コード間のデータ転送を可能にします。 インテル® DAAL と R の線形回帰を統合するため、 ファイルからデータをロードし、線形回帰モデルの訓練とテストを行うインテル® DAAL のラッパーを C++ で記述しました。 3 つのラッパーの実装の詳細は、 「電光石火の R マシンラーニング ・アルゴリズム」 9 を参照してください。
パフォーマンス ・ ゲインを評価するため、 R のネイティブコードで線形回帰の訓練 (lm 関数) とテスト (predict 関数)にかかった時間を測定します。 インテル® DAAL のラッパーでは、 インテル® DAAL の線形回帰の訓練とテストの主要関数 compute の実行時間を測定します。
表 2 は、 このケーススタディーで使用したデータセットの簡単な説明です。 各データセットの 75% を線形回帰の訓練に使用し、 残りの 25% をテストに使用しました。

次元縮小 : 多重共線性の検出と排除
安定した線形回帰モデルを得るためには、 データ内の予測的な特徴に多重共線性があってはなりません。 特徴のセットの相関性が高く、 互いの線を結合できる場合、 それらの特徴には多重共線性があります。 多重共線性を無視すると、 モデルが正しくない予測を行う可能性があります。 ここでは、 Naval propulsion plants (海軍の推進プラント) データセットを使用して、 特徴の多重共線性を検出する解析を実行します。 インテル® DAAL の距
離関数 correlation_distance と cosine_distance は、 異なる特徴変数間の相関を測定します。 データセットの調査中に、 スターボード (船の右舷側) のプロペラトルクとポート (船の左舷側) のプロペラトルクという 2 つの特徴が互いに重複していることに気付きました。 ボックスプロット10 を使用してこれらの特徴の値の分布をまとめました。 図 1 は、 両方のトルクの最小値、 下位四分位値、 平均値、 上位四分位値、 最大値を示したものです。 2
つのボックスプロットは全く同じです。 つまり、 2 つの特徴は相関性が高く、 両方の特徴を使用しても追加の詳

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

62

細は得られないため、 どちらか一方を排除できます。 特徴のデータ分布を観察中に、 ガスタービン圧縮機入口の空気圧と温度の 2 つの特徴は、 どちらも一様に分布しているため (図 2 と図 3)、 線形回帰モデルが不安定になることに気付きました。 同様の理由から、 16 個の特徴のうち 3 つを排除して、 海軍の推進プラント ・ データセットで線形回帰の訓練とテストを行いました。 別の方法として、 共線的な予測に対応できるリッジ回帰 (インテル® DAALに含まれる) を使用することもできます。

1

海軍の推進プラント・データセットの多重共線性のある特徴の分布

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

63

2

海軍の推進プラント・データセットのガスタービン圧縮機の入口の空気圧の一様分布

3

海軍の推進プラント・データセットのガスタービン圧縮機の入口の温度の一様分布

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

64

インテル® DAAL を使用したネイティブ R のスピードアップの解析
ここでは、シングルソケット、8 コアのノードで線形回帰を実行しました (表 1)。 システム雑音の影響を排除するため、各データセットで 10 回ずつ訓練とテストを実行しました。 図 4 は R とインテル® DAAL で拡張した R の線形回帰の訓練におけるスピードアップ、 図 5 はテストにおけるスピードアップを示しています。
図 4 と図 5 から、 すべてのデータセットで訓練とテストが大幅にスピードアップしていることが分かります。 しかし、
L3 キャッシュよりも小さなデータセットでは、 データセットのサイズによってインテル® DAAL と R を一緒に使用することで得られるパフォーマンス ・ ゲインに開きがあります。 訓練のスピードアップは、 大きなデータセットではほぼ横ばいです。 その 1 つの理由は、 大きなデータセットでは線形回帰のパフォーマンスがメモリーにより制限されるためです。 これは、 予備パフォーマンス解析で、 大きなデータセットでは演算強度が低くなったことによっても裏付けられます。 また、 バッチモードではインテル® DAAL の洗練されたデータ管理を利用できないため、 L3 キャッ
シュよりも大きなデータセットでは訓練とテストにおいて大幅なスピードアップが得られていません。

4

線形回帰の訓練のスピードアップ

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

65

5線形回帰のテストのスピードアップ

まとめ
線形回帰は、 予測に使用される一般的な統計アルゴリズムです。 いくつかのオープンソース ・ パッケージが線形回帰用の関数を提供しています。 インテル® DAAL は、 インテル® アーキテクチャー向けに高度に最適化されたデータ解析ライブラリーであり、 多数の統計マシンラーニング ・ アルゴリズムのチューニング済みの実装が含まれています。 ここでは、 インテル ® DAAL を利用することで R の線形回帰のスピードアップに成功しました。
訓練では最大 300 倍、 テストでは最大 373 倍のスピードアップが得られました。

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

66

参考資料
1. 線形回帰について (英語)
2. 演算強度とルーフライン ・ モデル (英語)
3. インテル® Software Development Emulator (英語)
4. UCI マシンラーニング ・ リポジトリー (英語)
5. 統計コンピューティング向けの R プロジェクト (英語)
6. R の線形回帰 (英語)
7. インテル® DAAL の線形回帰 (英語)
8. Rcpp: R と C++ のシームレスな統合 (英語)
9. 電光石火の R マシンラーニング ・ アルゴリズム
10. ボックスプロットについて (英語)BLOG HIGHLIGHTS
インテル ® Xeon Phi ™ プロセッサー上で MPI for Python* (mpi4py) を使用する
LOC Q NGUYEN (INTEL) ›メッセージ・パッシング・インターフェイス (MPI) は、 分散メモリー・プログラミング向けに標準化されたメッセージ・
パッシング・ライブラリー・インターフェイスです。 MPI は、分散メモリー・アーキテクチャーに適しているため、ハイパフォーマンス ・ コンピューティング ( HPC ) 分野で広く使用されています。
Python* は、 モジュールとパッケージをサポートする、 近代的で強力なインタープリターであり、 C/C++ 拡
張をサポートします。 多くの HPC アプリケーションは、 高速化のため C や Fortran で記述されていますが、Python* は単純でモジュールをサポートするため、 プロトタイプの概念実証を素早く作成したり、 迅速なアプリ
ケーション開発を実現できます。
MPI for Python (mpi4py) パッケージは、 Python* と MPI 標準をバインドします。
この記事の続きはこちらでご覧になれます。

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

Intel、 インテル、 Intel ロゴ、 Intel Core、 Xeon、 Intel Xeon Phi、 Intel GO、 VTune は、
アメリカ合衆国および / またはその他の国における Intel Corporation の商標です。
* その他の社名、 製品名などは、 一般に各社の表示、 商標または登録商標です。
© Intel Corporation