オープン・データ・サイエンス向け
Python* の強化インテル® VTune™ Ampliﬁer XE を利用した Python* コードの高速化

インテル® MPI ライブラリーを利用した
Python* の並列プログラミング

00001101
00001010
00001101
00001010
01001100
01101111
01110010
Issue
01100101
01101101
00100000
2016
01101000
01110001
01110011
0111010125

目次

The Parallel Universe

編集者からのメッセージ
HPC の大衆化

2

3

注目記事

James Reinders

インテルと Anaconda* によるオープン・データ・サイエンス向け
Python* の強化
ビッグデータの課題への取り組みを保証するテクノロジー

4インテル® VTune™ Ampliﬁer XE を利用した Python* コードの高速化

15

インテル® MPI ライブラリーを利用した Python* の並列プログラミング

22

非常に低いオーバーヘッドで行レベルのプロファイリング情報を提供

パフォーマンスを向上するためのガイドラインとツール

間接呼び出しと仮想関数の呼び出し :インテル® C/C++ コンパイラー 17.0 によるベクトル化

最新のインテル® C++ コンパイラーでサポートされたベクトル化方式の SIMD 対応関数の間接呼び出し

次の記事については、The Parallel Universe Magazine Issue 25 (英語) をご覧ください。

The Other Side of the Chip (チップの別の側面)

A Runtime-Generated Fast Fourier Transform for Intel® Processor Graphics(インテル® プロセッサー・グラフィックス向けランタイム時に生成される高速フーリエ変換)

Optimizing an Illegal Image Filter System ( 不正イメージ・フィルター・システムの最適化)

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

30

編集者からのメッセージ
The
The
Parallel
Parallel
Universe
Universe

3

James Reinders 並列プログラミングのエキスパート。

『 Intel® Xeon Phi™ Processor High Performance Programming―Knights Landing Edition 』 (2016/6) 、『 High『Multithreading
Performance Parallel Programming Pearls』 (第 1 巻 2014、第 2 巻 2015) の共著者で、このほかに、『 Intel® Xeon Phi™ Coprocessor High Performance Programming 』 (2013、日本語 :for Visual Effects 』 (2014) 、『インテル® Xeon Phi™ コプロセッサー ハイパフォーマンス・プログラミング』) 、『Structured Parallel Programming 』『 Intel® Threading Building Blocks: Outfitting C++ for Multicore(2012、日本語 : 『構造化並列プログラミング』) 、Processor Parallelism』 (2007、日本語 : 『インテル スレッディング・ビルディング・ブロック―マルチコア時代の C++ 並列『 VTune™ Performance Analyzer Essentials 』 (2005) などのプログラミング』、中国語、韓国語の翻訳版があります) 、
文献を発表しています。

HPC の大衆化

Python* は、その単純性、構文の表現力、豊富なライブラリーにより、脚光を浴びています。このオープンソース・プログラ

ミング言語は、特にデータ解析とマシンラーニングの分野で広く採用されています。では、開発者は、Python* の生産性の利点と並列コンピューティングでのみ実現できるパフォーマンスをどのように組み合わせれば良いのでしょうか。

まず手始めに、インテルは、インテル® マス・カーネル・ライブラリー (インテル® MKL) を活用して Python* パッケージのパフォーマンスを引き出す、ベータ版 インテル® Distribution for Python* をリリースしました。また、インテル® VTune™

Amplifier XE のような一般的なツールにも Python* のサポートを追加しています。最新バージョンのインテル® VTune™

Ampliﬁer XE (インテル® Parallel Studio XE 2017 に含まれています) では、Python* コードとネイティブ C/C++ コードおよびエクステンションが混在したアプリケーションの隠れたパフォーマンス hotspot を特定できるようになりました。

この号では、これらのツールの一 部を取り上げています。注目記事、「インテルと Anaconda* によるオープン・

データ・サイエンス向け Python* の強化」では、ビッグデータ・プロジェクトを始めたばかりの開発者でも利用でき

る、最先端のオープンデータ・サイエンス・プラットフォーム Anaconda* について説明します。
「インテル® V Tune™

Amplifier XE を利用した Python* コードの高速化」では、Python* コードのプロファイルと最適化について説明します。また、「インテル® MPI ライブラリーを利用した Python* の並列プログラミング」では、HPC で最もよく使用されているプログラミング・モデルと Python* を組み合わせた並列プログラミングの方法について説明します。

これらの弛まぬ努力は、インテル® Xeon® プロセッサーおよびインテル® Xeon Phi™ プロセッサー/コプロセッサーの真の実

力を引き出せるように開発者を支援するという目的だけでなく、テクニカル・コンピューティングと HPC の大衆化におけるリーダーとしてインテルがより大きな使命を果たすためにも役立っています。Parallel Universe では、並列コンピューティン

グの最も注目されるユースケースを紹介するように努めていますが、現在のスーパーコンピューターの技術は 10 年も経たな

いうちにありふれたものになり、その後しばらくすると日常に溶け込んでいることでしょう。HPC の大衆化は非常に喜ばしいことです。技術の成熟とともに、インテルはハイパフォーマンス・システムをより利用しやすくする方法を見つけ出しています。このインテルの取り組みは、そのようなコンピューターを利用する、より先進的な科学/エンジニアリングに活力を与えます。そして、これらの技術が、形を変えて我々の将来を明るく照らすことになるのです。

James Reinders
2016 年 7 月

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

The Parallel Universe

4

インテルと ANACONDA* によるオープン・データ・サイエンス向け
PYTHON* の強化

ビッグデータの課題への取り組みを保証するテクノロジー
Travis Oliphant Continuum Analytics 設立者兼 CEO

現在、最も注目されている計算分野は、ハイパフォーマンス・コンピューティング (HPC)、ビッグデータ、デー
タサイエンスでしょう。しかし、最近まで、これらの分野には関連性はほとんどありませんでした。ハード
ウェアの進歩は HPC における大躍進の原動力となりましたが、オープン・データ・サイエンス (ODS) では、
Python* および R* コミュニティーからのフィードバックに依存しているのが現状です。

最適化を行わないと、Python* のような高水準言語は、大きなデータセットの解析に必要なパフォーマンスが得られません。幸いなことに、Continuum Analytics (Anaconda* の設立者および作成者) は、最先端の計算速度と開発の容易さを結び付ける方法を見つけました。

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

The Parallel Universe

5

Anaconda* は、インテル® マス・カーネル・ライブラリー (インテル® MKL) がリンクされたハイパフォーマンスな
Python* ディストリビューションを含む、優れた ODS プラットフォームです。Python* を始めたばかりの開発者でも利用可能な、ビッグデータ・プロジェクトへの取り組みを支援する強力なパッケージとテクノロジーを提供します。Anaconda* は、高度な解析、数値計算、JIT コンパイル、プロファイリング、並列処理、対話型の視覚化、コラボレーション、その他のニーズをサポートします。
最近の HPC の進歩と Python* ベースのデータサイエンスを組み合わせることにより、Anaconda* コミュニティーは、業界の将来を特徴付けるビッグデータの課題への取り組みを保証する高性能の (低コストで使いやすい) 解析テクノロジーの開発に取り組んでいます。

ODS と Python* でデータサイエンスの革新を加速

科学計算およびデータサイエンスの世界では、2 つのオープンソース言語、Python* および R* が利用されています。これらの言語は、ドメイン・エキスパート (金融アナリスト、データ・サイエンティスト、データエンジニア、
ビジネスアナリストなど) に、熟練したプログラマーになることなく、解析ニーズに集中できる環境を提供します。

Python* は特に親しみやすい言語です。世界中のコンピューター・サイエンスの教室で教えられ、コミュニティー
( Pythonic」であること)で活発に議論されています。Python* は、シンプルで読みやすいコードを記述すること 「を特に重視しています。
「Zen of Python」でも述べられているように、「シンプルは複雑より良い」のです。

Python* はデータサイエンスに理想的な言語です。Anaconda* は、Python*、R*、Hadoop* および成長を続けるオープンソース・テクノロジーのパフォーマンスを最大化する強固な ODS プラットフォームを提供します。
Anaconda* は、さまざまなアーキテクチャー (Raspberry Pi* からハイパフォーマンス・クラスターまで) において
スケールアップとスケールアウトを実現し、企業の変化するパフォーマンス・ニーズを満たす柔軟性を備えています。
Python* には、「バッテリー同梱 (batteries included)」の哲学もあります。一般的なプログラミング・タスクを行うためにサイズの大きな標準ライブラリー・パッケージが用意されており、ポリシー・モデリングから化学まで、さまざまな分野に特化した多くのサードパーティー・ライブラリーと統合されます。Anaconda* プラットフォー
ムは、これらの標準パッケージを含んでいるだけでなく、パッケージを簡単に追加できます。Python* を使用するデータ・サイエンス・チームは、(パフォーマンスや使いやすさを犠牲にすることなく) 思いつくほぼすべてのものをモデル化することができます。プラットフォームは単純なインストールでそのまま利用できる機能を提供するため、これらのパッケージはデプロイ環境で簡単にセットアップすることができます。

単純性、寛容さ、パフォーマンスを備えた Python* と Anaconda* の組み合わせは、ドメイン・エキスパートやデー
タ・サイエンティストに (革新をもたらす) さまざまなモデルをテストおよび操作する環境を提供します。インテル
コーポレーションのチーフ・エバンジェリスト James Reinders は、「プログラミングを主要な作業であると考えないデータ・サイエンティスト、化学者、物理学者にとって、プログラミングは弊害となります。Python* のよ
うな環境を利用することは、必要なパフォーマンスを実現する合理的な投資であり、科学者はプログラミングではなく科学により集中することができるのです。
」と述べています。

ありがたいことに、ドメイン・エキスパートには、ODS で今日のハードウェアの計算能力を利用できるように支援する多くの Python* ベースのオプションがあります。下記に説明するテクノロジーはすべて、Anaconda*
Enterprise サブスクリプションに含まれており、開発環境に効率良く統合されます。また、これらはすべて、
科学者、経済学者、財界人を含む、プログラマーでない人でも利用できます。

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

The Parallel Universe

6

高速でシンプルなコードを実現する Python* のコンパイル

ドメイン・エキスパートが便利さを実感する Anaconda* の機能の 1 つは、ほかのすべての Python* 解析のベースとなる基本的な Python* 解析パッケージ、NumPy* に統合される Python* 用の Numba* 実行時 (JIT)
コンパイラーです。Numba* は、ユーザーが Python* コードのセクションを Python* デコレーター (関数の処理を修飾する機能) でマークできるようにします。マークしたセクションはマシンコードにコンパイルされ高速に実行されます。

Python* の解釈に依存する代わりにコンパイラーが生成したネイティブ・マシンコードを使 用することで、Python* の実行速度は 2 倍から 2,000 倍になります。パフォーマンスの向上に加えて、Numba* ではコンテ
キストの切り替えが必要ないため、プログラマーの精神的な負担も軽減されます。つまり、Numba* ユーザー
は、パフォーマンス・クリティカルなセクションを C/C++ や Fortran のような従来のコンパイル型言語に変更することなく、Python* エコシステム内ですべての操作を行うことができるのです。Anaconda* と Numba* で
NumPy* コードを最適化および単純化した、最新のオープンソース米国税金ポリシー・モデリング・プロジェク
ト TaxBrain* (taxcalc* パッケージを使用する Web アプリケーション ) は、Anaconda* の潜在能力を示す優れた例の 1 つです。
また、Anaconda* は、データ・サイエンス・チームが並列化により計算パフォーマンスを向上できるように支援します。単一行のデコレーターを挿入することにより、ユーザーは指定したスレッド数で実行するように関数に指示することができます。複数のスレッドに分割できるタスクの場合、Numba* は最近のプロセッサー (GPU を含む) の複数のコアを利用する非常に簡単な方法をプログラマーに提供します。例えば、Numba* で 1 行のコードを追加して 8 つのコアで同時に実行するように関数を修飾すると、速度は 8 倍になります。

Python* がアルゴリズムおよびデータ・サイエンス・アプリケーションの迅速な開発に理想的とされるのは、これらの速度の利点があるためです。
「Python* には、迅速な対話型開発用のさまざまなツールが用意されています。その並列計算機能は比類なきものであり、Anaconda* およびインテル ® MKL と組み合わせることで、Python* は開発者がマシンラーニングやディープラーニングのアルゴリズムの新しい境地に到達することを支援できるでしょう。」(James Reinders)

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

The Parallel Universe

7

Anaconda* は、ほかの HPC ツールとの相互運用性を向上するため、活発に開発を行っています。現在進行中のプロジェクトの 1 つは、インテル® スレッディング・ビルディング・ブロック (インテル® TBB) ライブラリーのインターフェイスを作成することです。このような相互運用性は、ODS の活動の特徴です。

インテル ® C++ コンパイラー (インテルベースのハードウェアのパフォーマンスをさらに向上) および将来も利用できる Python* スクリプト (新しいインテルの技術革新を利用してスケーリング) を使用する Anaconda* のパフォーマンス分散プロジェクトも進行中です。

Anaconda* とイン テル® MKL の 組 み 合 わ せ に よる Python* の重要な解析パッケージの最適化

Anaconda* は、最速の計算およびスループットのために最適化された、プリコンパイル済みのライブラリー
を提供するため、インテル® MKL により Python* の数値計算パフォーマンスを強化し、NumPy*、SciPy*、scikit-learn、Numexpr* を含む、最も一般的な Python* 数値解析ライブラリーの土台となる線形代数および高速フーリエ変換 (FFT) の演算性能を向上させました。インテル® MKL は、数値解析を 10 倍から 100 倍高速化します。
NumPy* には、少数の要素にのみ定義された基本的なカーネル関数を非常に大きな配列に対して自動的にマップする重要な機能があります。この基本的なカーネルは、典型的な NumPy* 関数呼び出しで何度も実行されます。基本的なカーネルは、通常、コンパイルされたコード (C、C++、Fortran) とともにビルドされるため、
NumPy* を本来の速度で実行できます。Anaconda* と Python* コンパイラーを利用することにより、これらの基本的なカーネルを Python* で記述し、単純な Python* 構文を使用して基本的なレベルで NumPy* を簡単に拡張することができます。これらのカーネルには、さらに多くの機能を提供するインテル ® MKL 機能への呼び出しを含めることもできます。

Anaconda* はインテル® MKL により拡張された多くの基本的な NumPy* 関数を提供するため、ユーザーは、
三角法、平方根、代数関数呼び出しを含む、一般的に使用される関数をそのまま利用して、優れたパフォー
マンスを得ることができます。
「インテル® MKL のおかげで、今日の NumPy* および SciPy* ユーザーは、1 行のコードも変更することなく、アプリケーションのパフォーマンスを大幅に向上することができます。」(James
Reinders)

ODS の強力で柔軟な分散コンピューティング

パフォーマンスをさらに向上するため、Anaconda* を使用するデータ・サイエンス・チームは、高速な数値解
析のために低オーバーヘッドと低レイテンシーおよび最小限のシリアル化で動作する、強固かつハイパフォーマ
ンスな並列計算フレームワークを活用できます (図 1)。HPC および Hadoop* クラスターで解析ワークロードの
柔軟な分散処理が可能です。

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

The Parallel Universe

18

並列化の種類Anaconda* は、計算用によく知られた配列形式またはデータフレーム・コードを記述するための高水準インターフェイスをデータ・サイエンス・チームに提供します (図 2)。新規または既存の Python* スクリプトは、タスクの有向非巡回グラフ (DAG) に変換されます。これらの DAG は、大きなワークロードを多くのより小さな処理タ
スクに分割します。DAG は、ビルトインまたは独自のタスク・スケジューラーにより実行できます。Anaconda*には、単一マシンまたは HPC や Hadoop* クラスターのノードにわたるマルチスレッド、マルチプロセシング、分散処理に対応したスケジューラーが用意されています。クラスターは、クラウドベースまたはベアメタルのクラスターになります。DAG は、マルチコア CPU でよく知られた配列またはデータフレーム操作を使用して、数十GB あるいは数百 GB のデータを非常に素早く処理することができます。

2

Anaconda* の並列計算フレームワーク

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

The Parallel Universe

9

パフォーマンスの利点は、最近のハードウェアに非常に適したタスクの配列計算と自動チャンクによるものです。
例えば、Anaconda* は、1,000 万行の配列を 1,000 万行のセグメントに分割するため、DAG は大きな配列チャンクの各ワークの関数に対して多くの呼び出しを行います。このアプローチは、金融計算では非常に一般的です。
Anaconda* は、この手法を広範に適用します。DAG は Python* ディクショナリーとして表現されるため、データ・
サイエンス・チームは DAG を柔軟に変更できます。必要に応じて、チャンクを変更したり、呼び出しを挿入します。
次に、グラフは、マルチスレッド、マルチプロセシング、マルチノードの分散処理のために、3 つのビルトイン・
スケジューラーのいずれかに送られます。既存のスケジューラーが解析に適していない場合、Anaconda* の開発者はゼロからまたはビルトイン・リファレンスを変更して、独自のスケジューラーを作成することができます。
図 3 は、分散型スケジューラーの例です。

3分散型スケジューラーの例

単一マシンでは、Anaconda* はストレージまたは共有メモリーからデータを処理して、最近の CPU のコアをすべて使用します。クラスターでは、Anaconda* はデータ・サイエンス・チームが多くのノードに新しいアルゴ
リズムをプロトタイプして配備できるようにします。テキスト処理、統計、マシンラーニング、画像処理では、
PySpark* の 10 倍から 100 倍高速化されます。
図 4 は、マシンラーニング・パイプラインの例です。

4

マシンラーニング・パイプラインの例

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

The Parallel Universe

10

並列計算フレームワークは、データサイエンスに特に適しています。NumPy* と同じ API および一般的な
pandas* ライブラリーを使用します。同じ API 呼び出しで、コードを並列に実行できます。例えば、メニーコアのインテル® Xeon Phi™ コプロセッサーを 2 つの並列メソッド呼び出しで使用している場合、Anaconda* は解析速度を何倍にもすることができます。幸い、利用可能なすべての高水準手法において、Anaconda* は簡単に使用でき、利点を得るために並列処理の知識は必要ありません。
図 5 は、マシンラーニング・パイプラインとグリッドサーチの例です。

データ・サイエンス・チームは、配列コンピューティング形式
で 1 回コードを書くことにより、Anaconda* でハードウェアの能力を簡単に引き出すことができます。Anaconda* は、このコードを並列化して、コアまたはノードの処理速度を自動的に最大化することができます。
「PyData」スタックで構築された
Anaconda* の並列計算フレームワークは、気候科学 (xarray)、
画像処理 (scikit-image)、ゲノミクス (scikit-allel)、マシンラー
ニング (scikit-learn) を含む、さまざまな分野向けに設計されたパッケージの速度を向上します。

データとワークロードの変化によって生じるボトルネックや競合
ポイントの特定には、Anaconda* のプロファイラーと診断が役立ちます。見つかったボトルネックは、DAG を変更して修正することができます。この方法では、最初の DAG をベースにして、常に変化するデータやクラスターに合わせて、迅速かつ柔軟に対応することができます。並列計算フレームワークは、弾力性があり伸縮自在です。含まれているリソース・スケジューラー (マルチスレッド、マルチプロセシング、分散処理 ) は、Torque*、
Slurm*、YARN* を含むサードパーティーのスケジューラーと統合できます。この柔軟性とパフォーマンスにより、Anaconda*
は最良の価格 / 性能比でより短期間に価値を産み出せるように
インフラ投資を最大化します。

5

マシンラーニング・パイプラインとグリッドサーチの例

プロプライエタリーなソリューションに対する利点により、オープンソース・
ソフトウェアの利用は増加しています。

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

The Parallel Universe

11

インテル® VTune™ Ampliﬁer XE と Dask.diagnostics* を使用した
Python* のプロファイリング

データ・サイエンス・チームがパフォーマンス問題に取り組む最良の方法の 1 つは、プロファイリングを利用することです。インテルと Continuum Analytics は、Python* コードのプロファイリングを支援する機能を提供しています。

関数のプロファイリングについては、関数のタイミングデータを収集する cProﬁle が Python* の標準ライブラ
リーにすでに含まれています。SnakeViz (cProﬁle のモジュールの出力を表示するブラウザーベースのグラフィカ
ル・ビューアー ) は、プログラマーがボトルネックを特定できるようにパフォーマンス情報を表示します。ユーザー
は、heapy および line_proﬁle パッケージを使用して、Python* のメモリーおよび行プロファイリングを実行することもできます。

これらはパフォーマンス・ボトルネックを特定する便利なツールですが、配列やデータフレームを含む大規模な計算のプロファイリング中に、プログラマーがパフォーマンス問題を解決する手助けとはなりません。多くのプロファイリング・ツールは関数の実行にかかる時間を示しますが、その関数に渡された引数の詳細情報を提供することはまれです。例えば、引数がスカラー、ディクショナリー、配列であることは示されますが、配列のサ
イズ、型、形状は示されません。インテル® VTune™ Ampliﬁer XE のような高度なプロファイリング・ツールは、ロックで待機しているスレッドを含め、Python* およびネイティブコードの行レベルで特定の関数がどのように呼び出されているか詳細に示します。多くのビッグデータ・アプリケーションでは、パフォーマンス hotspot や
ボトルネックを診断する際にこれらの情報が重要になります。

Anaconda* はインテル® MKL により拡張された NumPy* 関数を提供するため、ユーザーは優れたパフォーマンスを得ることができます。
この種のプロファイリングは、クラスターの並列計算ではさらに困難になります。パフォーマンス・ボトルネックの影響を評価できるように適切な診断および可視性を得ることは、データ・サイエンス・チーム全体にとって重要です (特にクラスターでスケーリングする場合)。

幸い、クラスターの並列コードのプロファイリングは Anaconda* でも行うことができます。Anaconda* には、
この困難なタスクを支援するためのさまざまな機能が用意されています。スケジューラーのコールバックで分散
スケジューラーの実行を調査できます。進捗バーは長い計算の完了状況を示します。分散スケジューラー用のプロファイラーは、スケジューリング、リソース、キャッシュ (開始時間と終了時間など)、メモリー、CPU 使用率、
サイズメトリックおよびその他の値についての情報を提供します。

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

The Parallel Universe

12

価格 / 性能比と HPC データサイエンス

データ・サイエンス・チームが (プロプライエタリーまたは ODS ソリューションの) どちらのソフトウェア・エ
コシステムを選択した場合でも、コストが問題になります。かつて、データストレージはコストを左右する大きな要因でした。しかし、現在では、ストレージの 1 テラバイトあたりの価格は大幅に低下しています。

このコストの低下により、ビッグデータを扱えるようになりましたが、データ処理コストが無関係になったわ
けではありません。今日多くの場合、価格 / 性能比でこれらのコストが評価されます。多くのチームは、この比率を低く抑え、安価に格納した大量のデータから有用な結果を得ようとしています。

データ・サイエンス・チームがシステムの価格 / 性能比を低く抑える 1 つの方法は、ODS を採用することです。このアプローチは、ハードウェアで多くの進歩があった場合にも引き続き利用できます。ハードウェアの処理能力が増加するとともに、パフォーマンス特性も向上します。企業がより新しいハードウェアで既存のソフトウェアを実行できる場合、全体的なコストが削減され、価格 / 性能比は低くなります。新しいハードウェ
アがリリースされたときに新しいソフトウェアを購入すると、新しいソフトウェアのライセンス料、トレーニング・
コスト、開発者がシステムを学び直したりコードを書き直したりするために必要な時間が発生するため、この比率は高くなります。

ODS は、価格 / 性能の面で利点があります。これまで紹介したテクノロジーの多くはオープンソースです。
無料で利用でき、相互運用可能で、オープンソース・コミュニティーにより絶えず更新されています。これらのオープンソースのツールはプロプライエタリーでないため、ベンダーのリリース・スケジュールやライセンスに制限されません。
これらのプロプライエタリーなソフトウェアのコストは、解析製品のライセンスの購入や更新によるものです。
また、コンサルタントやアドオンパッケージにもコストがかかります。プロプライエタリーなソフトウェアにかかるコストは増えることはあってもなくなることはありません。

一方、オープンソース・ソフトウェアを利用すると、これらのコストの多くは大幅に減るか不要になります。
これまでに紹介したものも含め、多くの ODS パッケージは無料で簡単にインストールできます。さらに、プ
ロプライエタリーなソフトウェアのライセンスおよび更新に相当するコストは発生しません。 ODS コミュニティーが無料のサポートを提供しているため、法外なコンサルタント費用が含まれることはまれです。
誤解のないように言っておきますが、ODS はすべてのコストを消し去る魔法の杖ではありません。ODS ア
プローチを採用した場合でも、オープンソース・パッケージを使用した SaaS 製品には開発者のコストがかかります。もちろん、ハードウェア・コストも、解析の総コストに含まれます。

多くの場合、解析に対する純粋なオープンソースのアプローチには予期しない問題も発生します。 ODS ベンダーによるサポートがない場合、ソフトウェアをセットアップおよび保守するエキスパートが必要になるため、ソフトウェアの実装コストは跳ね上がります。満足するソリューションを提供できるエキスパートを見つける
ことは困難です。

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

The Parallel Universe

13

変化の速度
これは業界全体で進行中の大きな変化です。 TaxBrain* のような公共部門のプロジェクトは、ODS がビジネス、政府、ソーシャルグッドの変化に大きな役割を果たしていることを示しています。金融サービスでは、クオンツ、トレーダー、
デベロッパー、アナリストで構成されるさまざまなチームで、ODS ソリューションを利用しています。

ビジネス界では、Anaconda* による対話型視覚化の進歩によって、多くの企業がビッグデータ・アプリケーションを利用して、有用なデータと大きなビジネス価値を得ています。

多種多様な分野において ODS という共通のアプローチにより、財界人から物理学者、開発者、個人までもが利益を得ることができます。ODS と HPC を結び付ける新しいツールのおかげで、データによって世界を理解する進歩のペー
スはさらに速くなるでしょう。

HPC、ビッグデータ、高度な解析はもはや無関係ではありません。組織が未活用データの価値をコスト効率良く利用するには、オープン・データ・サイエンスを採用するべきです。オープンソース・テクノロジーは高速化のために構築されたものではありません。しかし、今日のビジネスでは、スピードが求められています。インテル® MKL により強化された Anaconda* のハイパフォーマンスな解析により、データ・サイエンス・チームは急激な変化にも簡単に対応することができるでしょう。

また、組織が独自に ODS エコシステムを管理している場合、組織の方針変更による影響を受けます。その組織に特有のシステムになりがちなため、内製のソフトウェア (以前の担当者がフリーソフトに手を加えて構築していることもあります) からオープンソース・ソフトウェアへのデータや人的リソースの移行は困難になります (特にハードウェアの変更を伴う場合 )。データサイエンスのように革新的で個別に調整が必要な分野では、隠れたコストは多くのマネージャーが考えているよりも大きくなります。

これらの隠れたコストは、理想化されたゼロコストのデータ・サイエンス・アプローチでも、実際には想定以上のコストがかかることを意味します。徹底的にテストされ、完全に互換性がある、定期的に更新されるソフトウェ
アのエコシステムを提供する ODS ベンダーが、総保有コストの点で勝者となるでしょう。

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

The Parallel Universe

14

ODS コミュニティーとデータサイエンスの未来

ODS は、革新や低コストにのみ取り組むのではなく、コミュニティーにも力を入れています。

Python* と ODS は、コミュニティーにより構築されたソフトウェアの優れたモデルです。プロプライエタリー
なソリューションに対する利点により、オープンソース・ソフトウェアの利用は増加しています。毎年、新しい
Python* 開発者が大学の教育課程から誕生しています。これらの開発者は、GitHub や StackOverﬂow のよ
うなオンライン・ソフトウェア・フォーラムに参加して、オープンソース・ソフトウェアのパッチを提供したり、独自のオープンソース・プロジェクトを開始しています。ODS の明白な利点により、データ・サイエンティストやド
メイン・エキスパートは Python* やそのパッケージスイート (NumPy*、pandas*、matplotlib、dask、scikitlearn、その他を含む ) を学んでいます。

優れた ODS プラットフォームである Anaconda* は、データ・サイエンス・チームが、高価値で影響力のある
データ・サイエンス・ソリューションの作成に集中できる、新しい時代への門戸を開きました。Anaconda* は、
現在、そして成長し続けるスケーリング要件に簡単に対応することができるでしょう。

参考資料 (英語)
Numba* >Anaconda* のサブスクリプション >オープン・データ・サイエンス >Anaconda* ホワイトペーパー : オープン・データ・サイエンスの旅 >インテル® VTune™ Amplifier XE を評価する

インテル® Parallel Studio XE Professional Edition に含まれます >コンパイラーの最適化に関する詳細は、最適化に関する注意事項を参照してください。

The Parallel Universe

15

インテル® VTUNE™ AMPLIFIER XE を利用した PYTHON* コードの高速化
非常に低いオーバーヘッドで行レベルのプロファイリング情報を提供

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

インテル® VTune™ Ampliﬁer XE 2017 (インテル ® Parallel Studio XE に含まれる) では、Python* スクリプトを解析してアプリケーションで時間が費やされている場所を正確に特定できるようになりました。この記事では、
この新しいインテル® VTune™ Ampliﬁer XE の Python* 機能の使用方法について説明します。

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

The Parallel Universe

16

Python* の最適化が必要な理由• Python* は、アプリケーションのパフォーマンスが重要なケースを含め、広範なソフトウェアで使用されています。例 : Web サーバーコード、複雑な自動化スクリプト (ビルドシステムを含む)、科学計算。
• Python* はコードを素早く記述できますが、プロセスに十分なワークロードが与えられないと、コードが適切にスケーリングしません。

最適化が必要なコードの場所の特定
次のような方法があります。

• コードの調査。コードエディター以外のツールを必要としない、最も簡単な方法ですが、作業は簡単ではありません。特定のコードがどのように実行されるか正しく理解している必要があります。理解すべき情報が多すぎるため、非常に小さなコードベースを除いて適していません。

• ログ収集。タイムスタンプを記録する特別なバージョンのソースコードを作成する方法です。記録を確認してコードの遅い部分を調べます。この解析は骨の折れる作業であり、ソースの変更も必要です。

• プロファイル。プロファイルは、特定のワークロードの下でアプリケーションの動作を示すいくつかのメトリックを収集します。この記事では、CPU hotspot プロファイル (大量の CPU サイクルを費やしている
関数の検索およびチューニング) について説明します。ロックの待機、メモリー消費などのプロファイルも可能ですが、典型的な Python* アプリケーションでは、CPU 使用率が問題になることが多く、CPU
hotspot を調べることにより、メモリー消費ポイントを特定できます (特に大きな Python* シーケンス・オ
ブジェクトを処理する場合、メモリーの割り当てと解放により CPU 使用率が非常に高くなります)。

アプリケーションをプロファイルするツールが必要になりますが、ツールの導入により得られる生産性の向上は十分に価値のあるものです。

既存のツールの概要

イベントベースのツールは、関数の入口 / 出口、クラスのロード / アンロードなど、特定のイベントでデータを収集します。
ビルトイン Python* cProﬁle プロファイラー ( および sys.setproﬁle /sys.settrace API) はイベントベー
ス収集の例です。

インストルメンテーションベースのツールは、データを収集するためにターゲット・アプリケーションを変更します。
この変更は、手動で行うか、コンパイラーやほかのツールを使用して行います。

統計ツールは、一定の間隔でデータを収集します。最も頻繁に実行された関数が、「関数別サンプル」分布の一番上になります。これらのツールはおおよその結果を提供し、プログラムの実行にあまり干渉しません ( ター
ゲット・アプリケーションへの影響はわずかで、小さな関数の頻繁な呼び出しにも影響を受けません )。また、
プロファイル・オーバーヘッドはワークロードにほとんど依存しません。

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

The Parallel Universe

17

イン テル® VTune™ Ampliﬁer XE を 利 用した Python* コ ードのプロファイルインテル® VTune™ Ampliﬁer XE で、Python* コードをプロファイルできるようになりました。非常に低いオーバーヘッド (Grand Uniﬁed Python* Benchmark で約 1.1 倍から 1.6 倍) で、行レベルのプロファイル情報を取得できます。Windows® および Linux* をサポートしています。主な機能は次のとおりです。

• Python* 32 ビットおよび 64 ビット• 2.7.x および 3.4.x ブランチ (2.7.10 および 3.4.3 でテスト)• SSH によるリモート収集のサポート• マルチスレッドのサポート、ズームおよびフィルター、ソースのドリルダウンを含む UI

次のワークフローをサポートしています。

• アプリケーションを開始して、終了を待機する。

• アプリケーションにアタッチし、すぐに短いプロファイルを行い、デタッチする。

• インタープリターの初期化および終了時に実行される多くの Python* コードを含む、すべての段階でコードをプロファイルする。

Python* コードを解析する手順は次のとおりです。

• インテル® VTune™ Ampliﬁer XE プロジェクトを作成する。
• Basic Hotspots 解析を実行する。
• 結果データを解釈する。

プロジェクトの作成

インテル® VTune™ Ampliﬁer XE でターゲットを解析するには、プロジェクトを作成して解析ターゲットおよびデータの収集方法を設定する必要があります。

a. amplxe-gui スクリプトを実行して、インテル® VTune™ Ampliﬁer XE の GUI を起動します。
b.

メニューボタンをクリックし、[New (新規)] > [Project... (プロジェクト ...)] を選択します。
[Create a Project (プロジェクトの作成)] ダイアログボックスが表示されます。

c. プロジェクト名を test_python にします。

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

The Parallel Universe

18

インテル® VTune™ Amplifier XE は、$HOME/intel/ampl/projects ディレクトリーの下に test_
python プロジェクト・ディレクトリーを作成して、[Choose Target and Analysis Type ( ターゲットと解析タイプの選択 )] ウィンドウの [Analysis Target ( 解析ターゲット)] タブを開きます ( 図 1) 。

a. 左ペインから [local (ローカル)] ターゲットシステム、右ペインから [Application to Launch ( 起動する
アプリケーション)] ターゲットタイプを選択します。
b. 右の設定ペインが更新され、選択したターゲットタイプに適用可能な設定が表示されます。
c. 次のようにターゲットを指定して設定します。
•
•
•
•

1

[Application (アプリケーション)] フィールドに、Python* 実行ファイルを指定します。

[Application parameters (アプリケーションのパラメーター)] フィールドに、Python* スクリプト
を入力します。
プログラムの作業ディレクトリーを指定します。

[Managed code proﬁling mode (マネージドコードのプロファイリング・モード)] プルダウンを使用して、[Mixed ( 混在 )] を指定します。

インテル® VTune™ Ampliﬁer XE でプロジェクトを作成する

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

The Parallel Universe

19

Basic Hotspots 解析の実行

a. 右の [Choose Analysis ( 解析の選択)] ボタンをクリックして、[Analysis Type ( 解析タイプ )] タブに切り替えます。
b. [Choose Target and Analysis Type (ターゲットと解析タイプの選択 )] ウィンドウで、[Analysis Type ( 解析タイプ )] タブに切り替えます。

c. 左の解析ツリーから、[Algorithm Analysis (アルゴリズム解析 )] > [Basic Hotspots (基本 hotspot)]
を選択します。
d. 右ペインが更新され、Basic Hotspots 解析のデフォルトオプションが表示されます。
e. 右のコマンドバーの [Start (開始)] ボタンをクリックして解析を実行します。

結果データの解釈

サンプル・アプリケーションが終了すると、インテル® VTune™ Ampliﬁer XE は結果をファイナライズして、
hotspot を表示します。ウィンドウまたはペインには、多くの CPU 時間を費やしたコード領域が表示されます。
サンプルコードのデータのパフォーマンスを解釈するには、次の操作を行います。

• Python* hotspot 解析により提供される基本的なパフォーマンス・メトリックを理解します。
• 最も時間を費やしている関数と CPU 使用率を解析します。
• スレッドごとのパフォーマンスを解析します。

Python* hotspot のメトリックを理解する[Summary (サマリー )] ウィンドウで解析を開始します。データを解釈するには、 アイコンの上にマウスのカー
ソルを移動して、ポップアップ・ヘルプを読み、各パフォーマンス・メトリックの意味を確認します。

サンプル・アプリケーションの [CPU Time (CPU 時間 )] は 7.004
秒です。これはすべてのアプリケーション・スレッドの CPU 時間の合計です。[ Total Thread Count (スレッドの総数)] は 3 で、サンプル・アプリケーションはマルチスレッド化されています。

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

The Parallel Universe

20[ Top Hotspots ( 上位の hotspot)] セクションには、最も時間が費やされた関数 (hotspot 関数) のデータがCPU 時間でソートして表示されます。

BLOG HIGHLIGHTS
インテル® Xeon Phi™ プロセッサー ( 開発コード名 : Knights Landing ) 向け
デベロッパー・アクセス・プログラム
MICHAEL P >インテルは、インテル® Xeon Phi™ プロセッサー ( 開発コード名 : Knights Landing) の一般販売に先立ち、このプロセッサー向けのデベロッパー・アクセス・プログラム (DAP) を開始しました。DAP は、インテル®
Xeon Phi™ プロセッサー・ベースのシステムを購入するための、世界中の開発者を対象とした早期アクセスプ
ログラムです。開発者が、コードの開発、アプリケーションの最適化、パフォーマンスの確認を開始できるよ
うに、単一のブート可能なインテル® Xeon Phi™ プロセッサー (開発コード名 : Knights Landing) を搭載した、スタンドアロンの筺体が用意されています。
この記事の続きはこちら (英語) でご覧になれます。

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

The Parallel Universe

21

混在モード解析を実行する

Python* はインタープリター型言語で、コンパイラーを使 用しないでバイナリー実行コードを生成します。
Cython も (拡張子は C ですが) インタープリター型言語で、ネイティブコードをビルドできます。インテル®
VTune™ Ampliﬁer XE 2017 は、ホットな関数のレポートにおいて Python* コードと Cython コードの両方をサポートしています。

まとめ

チューニングを行うと、コードのパフォーマンスを大幅に向上できます。インテル® VTune™ Ampliﬁer XE で、Python* コードをプロファイルできるようになりました。Python* コードの解析に加えて、Python*/Cython の混在コードの解析を行うこともできます。インテル® VTune™ Ampliﬁer には、パフォーマンス・ボトルネックを素早く特定できるように支援する強力な機能が用意されています。

Python* コードのプロファイルを今すぐ始めよう
インテル® Parallel Studio XE 2017 のダウンロード >コンパイラーの最適化に関する詳細は、最適化に関する注意事項を参照してください。

The Parallel Universe

22

インテル® MPI ライブラリーを利用した
PYTHON* の並列プログラミング

パフォーマンスを向上するためのガイドラインとツール

Artem Ryabov インテル コーポレーション ソフトウェア開発エンジニア
Alexey Malhanov インテル コーポレーション ソフトウェア開発エンジニア

ハイパフォーマンス・コンピューティング (HPC) はこれまで、Fortran や C のようなコンパイラー型言語を利用してソフトウェア開発が行われてきました。ところが最近では、Python* のようなインタープリター型高水
準言語でも、モジュールを利用して、モデリング、シミュレーション、設計などの科学 / エンジニアリング・
アプリケーションを簡単に開発できるようになりました。では、Python* で並列アプリケーションを作成することは可能なのでしょうか。

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

The Parallel Universe

23

この記事では、分散メモリーシステムの HPC で最もよく使用されているプログラミング・モデルである、メッセー
ジ・パッシング・インターフェイス (MPI) と Python* を組み合わせた並列プログラミングの方法について説明します。スクリプト言語と MPI 間のインターフェイスでよく発生する問題は、パフォーマンスに関するものです。

まず、ネイティブ MPI 実装 (インテル® MPI ライブラリー) の Python* ラッパーとして mpi4py を使用する、
並列 Python* アプリケーションの開発ガイドラインを説明します。mpi4py は、インテル® Distribution for
Python* (2017 以降 ) に含まれています。さらに、mpi4py を使用して記述した MPI アプリケーションのパフォー
マンス向上に役立つ手法と、インテル® Trace Analyzer & Collector のようなインテルのツールを使用して並列
Python* アプリケーションを解析する方法について説明します。

MPI for Python*

MPI for Python* (mpi4py) は、MPI にオブジェクト指向のアプローチを提供します。このインターフェイスは、
標準 C++ MPI バインドの MPI 構文とセマンティクスを Python* に変換するように設計されています。

一般に、mpi4py は、Python* オブジェクトのシリアル化機能を使用して、任意のビルトインまたはユーザー定義の Python* オブジェクトと通信します。特に大きなバッファーを転送する場合、シリアル化によりメモリーやプロセッサーの利用に著しいオーバーヘッドが発生します。幸い、mpi4py は、一部の型 ( 文字列や数値配列など ) で提供される標準 Python* メカニズムを備えたオブジェクトの直接通信をサポートしています。この機能は、C 側で、関連データを含む連続するメモリーバッファーへのアクセス (アドレスと長さ) を提供します。この
機能を、複雑なメモリーレイアウトを記述するユーザー定義の MPI データ型を構築する機能とともに利用す
ると、オーバーヘッドを気にすることなく多次元数値配列を含む多くのアルゴリズムを Python* で直接実装
して、コンパイルした Fortran、C、C++ コードとほぼ同じ速度で実行することができます。

使用法

図 1 は、mpi4py で記述された簡単な �Hello World� の例です。
from mpi4py import MPI
comm = MPI.COMM_WORLDsize = comm.Get_size()rank = comm.Get_rank()name = MPI.Get_processor_name()
if rank == 0:
print "Hello world: rank %d of %d running on %s" % (rank, size, name)for i in xrange(1, size):rank, size, name = comm.recv(source=i, tag=1)
print "Hello world: rank %d of %d running on %s" % (rank, size, name)else:
comm.send((rank, size, name), dest=0, tag=1)

1

サンプル・アプリケーション

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

The Parallel Universe24

この例で、comm はコミュニケーター・オブジェクトです。MPI 関数 Get_size()、Get_rank()、send()、recv() は、このコミュニケーター・オブジェクトのメソッドです。
図 1 の例は図 2 のコマンドを使用して実行します。
$ source <intel_mpi>/bin/mpivars.sh$ source <intel_python>/bin/pythonvars.sh$ mpirun -ppn 1 -n 2 -hosts node01,node02 python helloworld.py
Hello world: rank 0 of 2 running on node01
Hello world: rank 1 of 2 running on node02

2

コマンド

mpivars.sh スクリプトは、インテル® MPI ライブラリーの環 境を設 定します。pythonvars.sh は、インテル® Distribution for Python* の環境変数を設定します。mpirun ユーティリティーは、 MPI ア

プリケーションを起動します。

パフォーマンス

前述したように、mpi4py には 2 種類の通信があります。

• シリアル化ベースのジェネリック Python* オブジェクトの 通 信。mpi4py では、send()、recv()、
bcast() のように、(コミュニケーター・オブジェクトの) 小文字のメソッドです。送られるオブジェクトが通信呼び出しのパラメーターとして渡され、受け取ったオブジェクトが戻り値になります。

• バッファー 型オブジェクトの 通 信。Send()、Recv()、Bcast()、Scatter()、Gat her() のよ[d at a,うに、メソッド名が大 文 字で始まります。一 般に、これらの呼び出しのバッファー引数は、
M PI.D O U BL E] や [d at a, c o u nt, M PI.D O U BL E] のように、 リスト / タプルを使 用して明 示 的に指 定する必 要があります ( 前者はバイトサイズのデータと M PI データ型の範 囲を使 用してカウントを定義します ) 。

ジェネリック Python* オブジェクトの通信は、オブジェクトのシリアル化による追加のメモリー /CPU オーバーヘッドが発生し、パフォーマンスに影響することがあります。バッファー形式のオブジェクトの通信は、C に近い速度で行われるため、パフォーマンスへの影響はほとんどありません。

パフォーマンス向上のため、可能な場合は Python* インターフェイス・メソッドに大文字の MPI 通信を使用することを推奨します。

MPI for Python* とインテル® MPI ライブラリーのパフォーマンス向上のためのもう 1 つの推奨事項は、
I_MPI_SHM_LMT=shm 環境変数を指定して共有メモリーの大規模メッセージ転送メカニズムをオンにすることです (詳細は、インテル® MPI ライブラリーのドキュメントを参照) 。

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

The Parallel Universe

25

mpi4py とネイティブ MPI 実装

mpi4py のオーバーヘッドをネイティブ MPI 実装と比較すると、興味深いことが分かります。

容易さ

mpi4py は Cython 言語を使用して実装されています。Cython は Python* 言語に似ていますが、Cython
は C 関数呼び出しと C 型の変数宣言およびクラス属性をサポートしているため、コンパイラーは Cython
コードから非 常に効 率 の良いC コードを生成することができます。 このことから、Cython
mpi4pyは外部 C ライブラリーと高速な C モジュール をラップしてPython*Python* コードの実 行を高速
Cython化する理想的な言語と考えられ
Cythonています。Python* で MPI コー
C/C++/Fortranドを記 述すると、mpi4py は、インテル® MPI
ライブラリー
その部分を Cython を使 用した C の呼び出しに変換します。
パフォーマンス
図で示すと、図 3 のようになります。

3

mpi4py の仕組み

PYTHON を
さらにスピードアップ*

最速のプロセッサーでマシンラーニング Python* アプリケーションをより高速に実行。インテル® Distribution for Python* は、計算パッケージ (NumPy*、SciPy*/scikit-learn) が高速に実行されるようにコードを最適化します。

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

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

The Parallel Universe

26

MPI ポイントツーポイント操作のパフォーマンスを測定した結果は、この仕組みを裏付けるものとなりました(図 4)。同様の結果は集合操作にも当てはまります。

ポイントツーポイントのパフォーマンス測定には、osu_latency ベンチマークを使用しました。

システム構成 : ハードウェア : インテル® Xeon® プロセッサー E5-2699 v4 (2.20GHz)、64GB RAM、
インターコネクト : インテル® Omni-Path ホスト・ファブリック・インターフェイス。ソフトウェア : Red Hat*
Enterprise Linux* 7.1、ベータ版 インテル® C++ コンパイラー 2017、ベータ版 インテル® MPI ライブラリー
2017、OSU Micro-Benchmarks。各実行で I_MPI_SHM_LMT=shm 環境変数を使用。

4

パフォーマンス・テストの結果

解析結果から、MPI for Python* のパフォーマンスはかなり優れていることがわかります。mpi4py のパフォー
マンスは小さな / 中くらいのメッセージサイズではネイティブ MPI 実装よりも (最大 2.5 倍) 遅くなっていますが、
大きなサイズではほぼ同じです。

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

The Parallel Universe27

アプリケーション

Python* の柔軟性と MPI の優れた通信効率を利用するアプリケーションの数は急激に増加しています。有名な
プロジェクトの 1 つは、PETSc (Portable Extensible Toolkit for Scientiﬁc Computations) 向けの Python*
バインド、petsc4py です。PETSc は、偏微分方程式によりモデル化された科学アプリケーションを並列計算で解くためのデータ構造とルーチンのセットで、MPI をサポートしています。

MPI for Python* は、ParaView マルチプラットフォーム・データ解析 / 視覚化アプリケーションのコンポーネン
トとして、ユーザーが並列でフィルターを実行する必要がある場合に利用されます。また、天体物理学問題を解くための統合科学環境である yt プロジェクトでも、MPI for Python* を利用しています。

インテル® Trace Analyzer & Collector を使用したプロファイル

MPI for Python* アプリケーションは、インテル® Trace Analyzer & Collector を使用してプロファイルすることができます (図 5)。
$ source <itac _ dir>/bin/itacvars.sh$ export VT _ LOGFILE _ NAME=helloworld.stf$ export VT _ LOGFILE _ FORMAT=SINGLESTF$ export LD _ PRELOAD="<itac _ dir>/intel64/slib/libVT.so <impi _ dir>/intel64/lib/release _ mt/libmpi.so"$ mpirun -ppn 1 -n 2 -hosts node01,node02 python helloworld.py
Hello world: rank 0 of 2 running on node01
Hello world: rank 1 of 2 running on node02[0] Intel(R) Trace Collector INFO: Writing tracefile helloworld.stf in <dirname>5インテル® Trace Analyzer & Collector を使用したプロファイル

VT_LOGFILE_NAME および VT_LOGFILE_FORMAT 変数はオプションです。これらの変数は、主にトレースファイルを利用した操作に使用されます。図 5 のコマンドを実行すると、トレースファイル helloworld.stf およtraceanalyzer ユーティび補助ファイル helloworld.prot が生成されます。トレースファイルの確認には、リティーを使用します ( 図 6)。
$ traceanalyzer helloworld.stf &6

traceanalyzer ユーティリティー

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

The Parallel Universe

7

28

インテル® Trace Analyzer & Collector を使用した MPI for Python* アプリケーションのプロファイル

インテル® Trace Analyzer & Collector は低レベルの MPI 呼び出しをすべて表示するため、その一部はオリジナ
ルの MPI for Python* コードに存在しないことに注意してください (図 7)。この例では、Python* recv() から
MPI_Mprobe()/MPI_Mrecv() が生成されています。

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

The Parallel Universe

29

関連情報

1. インテル® MPI ライブラリー

2. インテル® Distribution for Python*

3. インテル® Trace Analyzer & Collector
4. mpi4py と VTK (英語 )5. mpi4py の公式ページ (英語 )6. PETSc (英語 )7.

yt プロジェクトの公式ページ (英語)インテル® ソフトウェア製品
技術ウェビナー
1 時間で学ぶコードの現代化。

最新の技術ウェビナーを追加しました。
インテルのエキスパートが、より高速で、より優れた
HPC アプリケーションの作成方法を解説します。

2016 年春 / 夏の技術ウェビナーシリーズ
ハイブリッド・プログラムの 理 解を深めよう >
インテル® TBB とヘテロジニアス・
コンピューティング >インテル® Fortran コンパイラーを利用して効率良く並列処理を最適化する ( 英語 ) >Spark* クラスターで高速な
データ・アプリケーションをビルドする ( 英語 ) >OpenMP*: メモリー共有型並列
プログラミングの先 ( 英語 ) >SDLT を利用して効率良くベクトル化する ( 英語 ) >ベクトル化するか、それともせずに滅びるか : 最新のインテル® AVX
SIMD 向けにチューニング ( 英語) >インテル ® MKL を利用して Python*のパフォーマンスを向上する ( 英語 ) >競合、デッドロック、メモリーの問題を解決する ( 英語 ) >NUMA のワークロードへの影響 :インテル® VTune™ Ampliﬁer XE( 英語 ) >インテル® VTune™ Ampliﬁer XE でPython* アプリケーションのパフォーマンスを解析する (英語) >インテル® IPP を利用してコードを高速化する ( 英語 ) >コンパイラーの最適化に関する詳細は、最適化に関する注意事項を参照してください。
© 2016 Intel Corporation. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴ、VTune は、アメリカ合衆国および / またはその他の国における Intel Corporation の商標です。
* その他の社名、製品名などは、一般に各社の表示、商標または登録商標です。

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

The Parallel Universe

30

間接呼び出しと仮想関数の呼び出し :インテル® C/C++ コンパイラー 17.0 によるベクトル化
最新のインテル® C++ コンパイラーでサポートされたベクトル化方式の SIMD 対応関数の間接呼び出しHideki Saito インテル コーポレーション 主任エンジニア、Serge Preis 同主任エンジニア、Sergey Kozhukhov 同シニア・ソフトウェア・エンジニア、Xinmin Tian 同主任エンジニア、Clark Nelson 同主任エンジニア、Jennifer Yu 同シニア・ソフトウェア・エンジニア、Sergey Maslov 同シニア・ソフトウェア・エンジニア、Udit Patidar 同プロダクト・マーケティング・エンジニア

Parallel Universe 22 号では、OpenMP* 4.0 仕様の SIMD サポート機能について取り上げました。OpenMP* 4.0の主要な機能の 1 つは、ユーザー定義関数 (SIMD 対応関数 ) のベクトル化が可能なことと、ベクトル化されたコードからベクトル化された SIMD 対応関数の呼び出しが可能なことです。SIMD 対応関数は、通常の関数およびサブルーチンでベクトル命令を使用して多くの要素のデータ並列コンテキスト (ベクトルループの内部または別の SIMD
対応関数の内部) で同時に操作を行うことにより、SIMD ハードウェアのプログラミング環境を大幅に向上します。

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

The Parallel Universe

31

これまでプログラマーにより記述されていた、実行ファイルでスカラー関数呼び出しをベクトル化された関数に置き換えるメカニズムは、どのスカラー関数が呼び出されたか判断するコンパイル時の静的な情報に依存していました。
その結果、多くの場合、ベクトル化された関数は直接呼び出しのみに制限されていました。

関数ポインターや仮想関数呼び出しによる間接関数呼び出しは、C++ のような現代のプログラミング言語の大きな特徴です。関数ポインターの主な利点は、実行時のポインターに基づいて実行する関数を選択する簡単な方法を提供して、アプリケーション・コードを単純化できることです。間接関数呼び出しの性質により、実際に呼び出される関数は実行時に決定されます。そのため、インテル® C++ コンパイラー 16.0 までは、これらの呼び出しがベク
トル化の前に直接呼び出しに最適化されない限り、ベクトル化されたコンテキスト内の間接呼び出しはすべてシリアル化されていました。コンパイラーはこれらの間接呼び出しをベクトル化できず、SIMD 対応ハードウェアのベク
トル機能を活用できないため、間接的に呼び出された SIMD 対応関数を実行すると大幅なボトルネックが発生していました。

間接関数呼び出しは C++ のような現代のプログラミング言語の大きな特徴です。

インテル® C++ コンパイラー 17.0 (インテル® Parallel Studio XE 2017 に含まれる) では、ベクトル化方式の SIMD
対応関数の間接呼び出しがサポートされました。また、SIMD 対応関数のポインターを宣言する新しい構文も追加されました。互換性規則のセットは、コンパイル時にスカラー関数の同一性を実際に解決するのではなく、異なるマッ
ピングでスカラー関数をベクトル化します。SIMD 対応関数の間接呼び出しを宣言して使用する例を次に示します。

1 つの SIMD 対応関数ポインターに、ポインターにより呼び出されるターゲット関数で利用可能なすべてのバージョンに対応した、複数の vector 属性を関連付けることができます。間接呼び出しを検出すると、コンパイラーは実引数の種類と関数ポインターで宣言されているベクトルバージョンを比較して、最適なバージョンを選択します。ベク
トル関数ポインター宣言と間接呼び出しを含む図 1 の例について考えてみます。

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

The Parallel Universe// ポインター宣言// ユニバーサルだが 3 つのループとも最も遅い定義と一致__declspec(vector)// 最初のループと一致__declspec(vector(linear(in1), linear(ref(in2)), uniform(mul)))// 2 つ目と 3 つ目のループと一致__declspec(vector(linear(ref(in2))))// 2 つ目のループと一致__declspec(vector(linear(ref(in2)), linear(mul)))// 3 つ目のループと一致__declspec(vector(linear(val(in2:2))))int (*func)(int* in1, int& in2, int mul);int *a, *b, mul, *c;
int *ndx, nn;...
// ループの例
for (int i = 0; i < nn; i++) {/** ループ内で 1 つ目の引数はリニアに変更される* 2 つ目の参照もリニアに変更される* 3 つ目の引数は不変*/
c[i] = func(a + i, *(b + i), mul);}for (int i = 0; i < nn; i++) {/** 1 つ目の引数の値は予測不可* 2 つ目の参照はリニアに変更される* 3 つ目の引数はリニアに変更される*/
c[i] = func(&a[ndx[i]], b[i], i + 1);}#pragma simd private(k)for (int i = 0; i < nn; i++) {/** ベクトル化により private 変数は配列に変換される :* k->k_vec[vector_length]*/
int k = i * 2;

}

1

/*
* 1 つ目の引数の値は予測不可* 2 つ目の参照と値はリニアであると見なせる* 3 つ目の引数の値は予測不可* (__declspec(vector(linear(val(in2:2)))) が* 一致する 2 つのバージョンの中から選択される )*/c[i] = func(&a[ndx[i]], k, b[i]);ベクトル関数ポインター宣言と間接呼び出しを含むループ

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

32

The Parallel Universe

33

SIMD 対応関数の直接または間接呼び出しでは、仮引数としてスカラー引数が指定されている部分に配列を与えます。並列コンテキスト内で SIMD 対応関数を間接的に呼び出すことも可能です。図 2 は、コンパイラーに特殊なベクトル命令を生成させることで命令レベルの並列処理を実現する 2 つの構文を示しています。

__declspec(vector)
float (**vf_ptr)(float, float);// 配列 a、b、c 全体に対して処理を行う
a[:] = vf_ptr[:] (b[:],c[:]);/** 配列表記構造で n (長さ) と s (ストライド) を* 指定する*/a[0:n:s] = vf_ptr[0:n:s] (b[0:n:s],c[0:n:s]);2

並列コンテキスト内で SIMD 対応関数の間接呼び出しを行うサンプルコード

インテル® C++ コンパイラー 17.0 ではベクトル化方式の SIMD 対応関数の間接呼び出しがサポートされました。
インテル® C++ コンパイラー 17.0 (この記事の執筆時点では製品化前のバージョンを使用しています) とインテル®
Xeon® プロセッサー E3-1240 v3 を使用したユニット・テスト・パフォーマンスの結果を図 3 に示します。ユニット
テストは、ループで FUNC() 関数を呼び出して合計リダクション操作を実行します。関数は直接呼び出し (シリアル化またはベクトル化) あるいは間接呼び出し (シリアル化またはベクトル化) です。ループの反復回数 NTIMES は、
ウォールクロック時間で 1 秒よりも長く実行するテストを設定します。図 4 は間接呼び出しのベクトル化のオーバーヘッドを示しています。ベースラインは、SIMD 対応関数機能を使用しないで関数を直接呼び出した場合です。最初に、�直接、ベクトル� の結果を見てみましょう。SIMD 対応関数機能を使用すると、4 つの倍精度計算が行われるため、パフォーマンスは約 4 倍になるはずです。TINY 計算テストモードでは、関数呼び出しのシリアル化のオー
バーヘッドは SMALL/MEDIUM モードよりも大きいため、相対的なパフォーマンスは約 5 倍でした。

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

The Parallel Universe

34

次に、�間接、シリアル� の結果を見ると、関数の間接呼び出しをシリアルに行った場合、(直接関数を呼び出した場
合よりも) オーバーヘッドは小さくなっています。最後に、�間接、ベクトル� の結果を見ると、間接ベクトル関数呼び出しのオーバーヘッドは TINY モードでは大きくなっていますが、計算量を増やすと小さくなります。すべてのベクトル要素が同じ関数を呼び出しているため、これは最高のシナリオと言えます。
double sum=0;#pragma omp simd reduction(+:sum)for (i=0;i<NTIMES;i++){sum += FUNC(i);}#ifdef SIMD_ENABLED_FUNC#pragma omp declare simd processor(core_4th_gen_avx)#endif__declspec(noinline)
double unit_test0(double x){
return COMPUTE(x);}インテル® C++ コンパイラー 17.0 でベクトル化された仮想関数のユニット・テスト・パフォーマンス測定に使用したサンプルコード。
3 サンプルコードは合計リダクション操作を実行します。

テストモードCOMPUTE(x)NTIMES

TINY

x+1

2,000,000,000

SMALL

exp(sin(x))

200,000,000

MEDIUMlog(exp(sin(x)))

200,000,000

ラベル

関数

SIMD_ENABLED_FUNC

SIMD_ENABLED_FUNC_PTR

直接、ベクトルX

unit_test0

○

N/A

直接、
シリアル
間接、
シリアル

間接、ベクトル

4

unit_test0
funcptr0[0]funcptr0[0]

間接呼び出しによるベクトル化のオーバーヘッド

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

X

○

N/A
N/A
○

The Parallel Universe35

図 5 は分岐呼び出しのオーバーヘッドを示しています。この例で、FUNC() は unit_test0() または
unit_test1() の直接呼び出しまたは間接呼び出しです (ループのインデックス値に依存します)。ここでは、SIMD 対応関数の間接呼び出しのオーバーヘッドに対する分岐のオーバーヘッドを強調するため、TINY 計算モードを使用しました。ベクトル長が 4 の場合、SIMD 対応関数呼び出しは MASKVAL=3 で 1 つのベクトル反復ごとに、
MASKVAL=15 で 4 つのベクトル反復ごとに、MASKVAL=63 で 16 のベクトル反復ごとに、それぞれ分岐します。
棒グラフの中央のセット �間接、ベクトル、同じ� は興味深い結果を示しています。このセットは 2 つの異なる関数ポインターを使用していますが、関数ポインターの実際の内容は同一であるため、最後の呼び出しは分岐せず、
コンパイラーがその点を利用したことがパフォーマンスに反映されています。棒グラフの左のセット �直接、ベクトル、異なる� および右のセット �間接、ベクトル、異なる� と比べて、分岐呼び出しを間接的に呼び出すオーバーヘッ
ドは実際の分岐により減少しています。
ラベル

直接、
シリアル、異なる直接、ベクトル、異なる間接、ベクトル、同じ
間接、ベクトル、異なる関数((i & MASKVAL) ? unit_test0: unit_test1)((i & MASKVAL) ? unit_test0: unit_test1)((i & MASKVAL) ?
funcptr0[0] : funcptr0[1])((i & MASKVAL) ?
funcptr1[0] : funcptr1[1])SIMD_ENABLED_FUNC

SIMD_ENABLED_FUNC_PTR

X

N/A

○

N/A

○

○

○

○

並列パフォーマンス
コードの能力を引き出すことは容易ではありません。
インテル® Parallel Studio XE を利用すれば、現在
および将来のハードウェアを最大限に活用できます。

•••

最先端のコンパイラー : インテル® C++/Fortran コンパイラー

実績あるライブラリー : インテル® MKL、インテル® TBB、インテル® IPP
マシンラーニングおよびデータ解析ツール : インテル® Distribution
for Python*、インテル® DAAL

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

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

The Parallel Universe

36

SIMD 対応仮想関数呼び出しの使用モデルは SIMD
対応メンバー関数呼び出しの使用モデルに似ていて、パフォーマンス特性は前述した間接呼び出しの例に似ています。コードの計算負荷の高い hotspotに間接呼び出しが含まれていて、ベクトル化が可能な場合、このインテル® C++ コンパイラー 17.0 の新機能を試してみると良いでしょう。

5

分岐呼び出しのオーバーヘッド

関連情報 (英語)SIMD 対応関数

SIMD 対応関数ポインター

ベータ版 インテル® PARALLEL STUDIO XE 2017 を
評価する
詳細 >

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

The Parallel Universe© 2016 Intel Corporation. 無断での引用、転載を禁じます。Intel、インテル、Intel ロゴ、Xeon、Intel Xeon Phi、VTune は、
アメリカ合衆国および / またはその他の国における Intel Corporation の商標です。* その他の社名、製品名などは、一般に各社の表示、商標または登録商標です。
OpenCL および OpenCL ロゴは、Apple Inc. の商標であり、Khronos の使用許諾を受けて使用しています。

Microsoft および Windows は、米国 Microsoft Corporation の、米国およびその他の国における登録商標または商標です。
コンパイラーの最適化に関する詳細は、最適化に関する注意事項を参照してください。

37