ベクトル化と SIMD 最適化

同カテゴリーの次の記事

インテル® Fortran および C++ コンパイラーで実装される OpenMP* 機能の調査

この記事は、The Parallel Universe Magazine 42 号に掲載されている「Vectorization and SIMD Optimization」の日本語参考訳です。


parallel_v42_05
[訳者注: 記事内のコンパイラー・メッセージは、日本語版のコンパイラーがインストールされている環境では日本語で表示されます。]

現代の CPU は複数のレベルで並列処理を行います。単一の CPU ノードにおける最大粒度の並列処理はマルチスレッド化です。命令レベルの並列処理を実現するため、CPU はパイプライン化を使用します[編集者注: パイプライン化の詳しい説明は、The Parallel Universe 32 号の「命令パイプラインに関する考察」を参照してください]。CPU における最小粒度の並列処理は、ベクトル化によるデータレベルの並列処理です。ベクトル化とは、同じ操作を一度に複数の要素に適用する CPU の機能です。

簡単に言えば、SIMD (Single Instruction, Multiple Data) 命令セットを使用してループを再構成して、ループの反復回数を減らします。例えば、インテル® Xeon® プロセッサーは、インテル® アドバンスト・ベクトル・エクステンション 512 (インテル® AVX-512) 命令セットをサポートしているため、32 ビットの float 型を処理する N 回の反復ループは、理想的なシナリオでは N/16 回実行され、16 倍のパフォーマンスを達成できます。

この記事では、インテル® C/C++ および Fortran コンパイラーのコンパイラー・レポートを使用して、アプリケーションをベクトル化する方法を紹介します。

コンパイラーによる最適化とレポート

可能な場合、インテル® C/C++ および Fortran コンパイラーは SIMD 命令を生成します。これは、コンパイラーの自動ベクトル化機能で、-O2 または -O3 コンパイラー・オプションを使用すると、デフォルトでベクトルコードが生成されます。しかし、ベクトルコードは常に生成できるわけではなく、生成できない場合、コンパイラーは最適化レポートにその理由を示します。Linux* および macOS* では -qopt-report[=n] オプションを、Windows* では /Qopt-report[:n] オプションを使用して最適化レポートを生成できます。n はオプションのレポートの詳細レベルです。有効な値は、0 (レポートなし) から 5 (詳細) です。n=1 から n=5 の各レベルでは、前のレベルのすべての情報と、レベルに応じた追加の情報が含まれます。

最適化レポート: ベクトル化 [vec]

リスト 1 は単純なベクトル加算コードで、図 1 はこのコードに関するコンパイラーの最適化レポートです。


リスト 1. 単純なベクトル加算コード

以下は、Windows* のコマンドラインです。

以下は、Linux* のコマンドラインです。


図 1. 単純なベクトル加算コードに関するコンパイラーの最適化レポート

レポートの最初のリマークは、vec01.cpp: line 20 にある外側のループに関するものです。コンパイラー・レポートは、外側のループはベクトル化されず、内側のループはベクトル長 4 でベクトル化されたこと (つまり、CPU は 1 つの命令で 4 つの整数要素を処理できること) を示しています。コンパイラーはまた、ベクトル実行とスカラー実行の潜在的なスピードアップも予測しています。

実際のスピードアップを確認するには、動的/ランタイム解析を行うインテル® Advisor を使用します。コンパイラーは、ベクトル化されたループの最大トリップカウントも予測しています。以下の式を使用して、おおよそのトリップカウントを計算できます。

このサンプルコードでは、1024/(4*4)=64 になります。この式は、ピールループとリマインダー・ループを考慮して調整する必要があります。ベクトル長が 4 であることから、SIMD 命令は 128 ビットのデータ (= 4 * 32 ビット整数) を処理したと推測でき、インテル® ストリーミング SIMD 拡張命令 (インテル® SSE) が使用された可能性が高いと考えられます。

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

関連記事

  • インテル® oneAPI を使用したヘテロジニアス ・プログラミングインテル® oneAPI を使用したヘテロジニアス ・プログラミング この記事は、The Parallel Universe Magazine 39 号に掲載されている「Heterogeneous Programming Using […]
  • インテルの CPU と GPU 向けの LLVM と GCC のベクトル化インテルの CPU と GPU 向けの LLVM と GCC のベクトル化 この記事は、The Parallel Universe Magazine 47 号に掲載されている「Vectorization in LLVM and GCC for Intel CPUs and […]
  • ベクトル化の効率を把握するベクトル化の効率を把握する アプリケーションがどの程度効率良くベクトル化されているか把握することは、システムで最高のパフォーマンスを達成するために非常に重要です。この記事では、インテル® Advisor を使用して、ベクトル化の問題をピンポイントで特定し、ハードウェアの使用効率を把握し、パフォーマンスを最適化します。インテル® Advisor […]
  • インテル Parallel Universe 36 号日本語版の公開インテル Parallel Universe 36 号日本語版の公開 インテル Parallel Universe マガジンの最新号が公開されました。 注目記事: CPU 上でのマシンラーニング/ ディープラーニング・プロジェクトの効率的な訓練と実行 掲載記事 Numba を使用した Python* […]
  • インテル Parallel Universe 33 号日本語版の公開インテル Parallel Universe 33 号日本語版の公開 インテル Parallel Universe マガジンの最新号が公開されました。 注目記事: BigDL により Apache Spark* 上で人工知能を向上 掲載記事 WebAssembly が Web 上のコンピューティングの未来を握る理由 コードの現代化を実践: […]