自動ベクトル化の使用

自動ベクトル化は、インテル® 64 (C++、DPC++、および Fortran) アーキテクチャーでサポートされます。ここでは、自動ベクトルの設定に役立つ情報を提供します。

ベクトル化によるスピードアップ

ベクトル化によるスピードアップはどのようにもたらされるでしょうか? 次に示すコード例について考えてみます。abc は整数配列です。

コード例

for (I=0;i<=MAX;i++)
   c[i]=a[i]+b[i];

ベクトル化が有効ではない場合 (つまり、O1-no-vec- (Linux*) または /Qvec- (Windows*) オプションを使用してコンパイルする場合)、コンパイラーはそれぞれの反復で各 SIMD レジスターに追加で 3 つの整数を保持できる空間があったとしても、それらを活用せずに (未使用のまま) コードを生成します。ベクトル化が有効な場合 (O2 以上のオプションを使用してコンパイルする場合)、コンパイラーは SIMD レジスターの未使用の空間を活用して、1 つの命令で 4 つの加算を実行します。デフォルトの最適化オプション (O2) 以上でコンパイルすると、コンパイラーは常にベクトル化の可能性を探します。

このオプションを使用すると、インテル製マイクロプロセッサーおよび互換マイクロプロセッサーの両方で、デフォルトの最適化レベルのベクトル化が有効になります。ベクトル化により呼び出されるライブラリー・ルーチンは、互換マイクロプロセッサーよりもインテル製マイクロプロセッサーにおいてより優れたパフォーマンスが得られる可能性があります。

適用されたループ変換と最適化の種類を確認するには、[Q]opt-report-phase オプションだけを指定するか、[Q]opt-report オプションと一緒に指定します。

パフォーマンスの向上はどの程度のものでしょうか? パフォーマンスの向上を評価するには、以下の例 vec_samples を実行してみてください。

  1. インテル® oneAPI DPC++/C++ コンパイラーのコマンドライン・ウィンドウを開きます。

    • Windows*:[スタート] メニューのインテル製品項目にある [Intel oneAPI 2021] > [Intel oneAPI Command Prompt] (インテル® oneAPI コンパイラーの場合) からアイコンを選択します。

    • Linux*および macOS*: <installdir> ディレクトリーにある vars.sh などの環境スクリプトを、アーキテクチャーに応じた属性を使用して source コマンドで実行します。

  2. <installdir>\Samples\<locale>\C++\ (C++) または <installdir>\Samples\<locale>\DPC++\ (DPC++) ディレクトリーに移動します。Windows* 上で、vec_samples.zip サンプル・プロジェクトを書き込み可能なディレクトリーに展開します。この小さなプログラム example1 は、次のループを使用してベクトルに行列を掛けます。

    ベクトル行列乗算の例

    for (j = 0;j < size2; j++) { b[i] += a[i][j] * x[j]; }
  3. 最初は自動ベクトル化を無効にして、プログラムをビルドし実行します。デフォルトの O2 最適化は、ベクトル化を有効にするため、別のオプションにより無効にする必要があります。プログラムの実行時間に注目してください。

    自動ベクトル化なしのアプリケーションのビルドと実行の例

    // (Linux* および macOS*)
    icx -O2 -no-vec  Multiply.c -o NoVectMult 
    ./NoVectMult
    // (Windows*)
    icx /O2 /Qvec- Multiply.c /FeNoVectMult 
    NoVectMult
  4. 次に自動ベクトル化を使用して、プログラムをビルドし実行します。プログラムの実行時間に注目してください。

    自動ベクトル化ありのアプリケーションのビルドと実行の例

    // (Linux* および macOS*)
    vicc -O2 -qopt-report=1 -qopt-report-phase=vec Multiply.c -o VectMult 
    ./VectMult
    // (Windows* - C++)
    icx /O2 /Qopt-report:1 /Qopt-report-phase:vec Multiply.c /FeVectMult 
    VectMult
    // (Windows* - DPC++)
    dpcpp /O2 /Qopt-report:1 /Qopt-report-phase:vec Multiply.c /FeVectMult 
    VectMult

2 つの実行時間を比較すると、ベクトル化されたバージョンのほうが速いことが分かるでしょう。ベクトル化されていないバージョンの実行時間は、O1 オプションでコンパイルした場合より多少早いだけです。

ベクトル化を妨げる要因

次に示す状況が必ずしもベクトル化を妨げるわけではありませんが、コンパイラーがベクトル化のメリットがないと判断する原因になります。

インテル® oneAPI DPC++/C++ コンパイラーのベクトル化を支援

場合によっては、コンパイラーがループのベクトル化を判断するための情報が不足していることがあります。コンパイラーに追加情報を提供する方法はいくつかあります。

関連情報