Parallel STL は、一般に C++17 と呼ばれる C++ 標準の次期バージョンの Working Draft N4659 で指定されている、実行ポリシーをサポートする C++ 標準ライブラリー・アルゴリズムの実装です。この実装は、ISO C++ Working Group Paper P0076R3 で指定されている、順序関係が存在しない実行ポリシーもサポートしています。

Parallel STL は、インテル® プロセッサー向けアルゴリズムの並列実行とベクトル実行の両方を効率的にサポートします。シーケンシャル実行は、C++ 標準ライブラリーの利用可能な実装に依存します。

Parallel STL は、インテル® Parallel Studio XE およびインテル® System Studio の一部として利用できます。

準備

Parallel STL を使用するには、次のソフトウェアをインストールする必要があります。

コマンドラインで Parallel STL を使用するアプリケーションをビルドするには、コンパイルとリンクの環境変数を設定する必要があります。これらの環境変数を設定するには、compilervars.{sh|csh|bat} のようなスイートレベルの環境スクリプトを呼び出すか、<install_dir>/{linux|mac|windows}/pstl/binpstlvars.{sh|csh|bat} を実行して Parallel STL の環境変数を設定します。

<install_dir> はインストール・ディレクトリーです。デフォルトでは次の場所にあります。

Linux* および macOS*:

Windows*:

Parallel STL の使用

次の手順に従って、アプリケーションに Parallel STL を追加します。

  1. コンパイラーのインクルード・パスに <install_dir>/pstl/include フォルダーを追加します。スクリプトを使用する場合は pstlvars スクリプトを呼び出します。

  2. コードに #include "pstl/execution" を追加します。次に、使用するアルゴリズムに応じて、次の行のサブセットを追加します。

    • #include "pstl/algorithm"
    • #include "pstl/numeric"
    • #include "pstl/memory"
  3. アルゴリズムと実行ポリシーを使用している場合は、std および std::execution 名前空間を指定します。この後の「サンプル」セクションを参照してください。
  4. 実装されているアルゴリズムでは、呼び出しの最初の引数として値の 1 つ (sequnseqpar または par_unseq) をアルゴリズムに渡して、実行ポリシーを指定します。ポリシーには次の意味があります。

    実行ポリシー

    意味

    seq

    シーケンシャル実行。

    unseq

    SIMD を使用します。提供されているすべての関数が SIMD セーフである必要があります。

    par

    マルチスレッドを使用します。

    par_unseq

    unseqpar の効果を組み合わせます。

  5. コードを C++11 (またはそれ以降) としてコンパイルし、ベクトル化のコンパイラー・オプションを使用します。

    • インテル® C++ コンパイラーの場合:
      • Linux* および macOS*: -qopenmp-simd または -qopenmp
      • Windows*: /Qopenmp-simd または /Qopenmp
    • ほかのコンパイラーの場合は、OpenMP* 4.0 SIMD 構造を有効にするオプションを使用します。

    優れたパフォーマンスを得るには、ターゲット・プラットフォームを指定します。インテル® C++ コンパイラーの場合、適切なオプションは次のとおりです。

    • Linux* および macOS*: -xHOST-xSSE4.1-xCORE-AVX2-xMIC-AVX512
    • Windows*: /QxHOST/QxSSE4.1/QxCORE-AVX2/QxMIC-AVX512
    異なるコンパイラーを使用している場合は、そのコンパイラーのドキュメントを参照してください。

  6. 並列処理を行うにはインテル® TBB ダイナミック・ライブラリーとリンクします。インテル® C++ コンパイラーの場合、次のオプションを使用します。

    • Linux* および macOS*: -tbb
    • Windows*: /Qtbb (オプション、#pragma comment(lib, <libname>) で処理)

マクロ

PSTL_USE_PARALLEL_POLICIES

マクロは、並列ポリシーの使用を制御します。0 に設定すると、par および par_unseq ポリシーが無効になり、これらのポリシーを使用するとコンパイル・エラーになります。unseq ポリシーのみを使用するベクトル化されたコードで、インテル® TBB ランタイム・ライブラリーへの依存を回避するために推奨します。マクロが定義されていない場合 (デフォルト)、またはマクロが非ゼロ値に評価された場合、すべての実行ポリシーが有効になります。

サンプル

サンプル 1

このサンプルはベクトル化された copy を呼び出します。

#include "pstl/execution"
#include "pstl/algorithm"
void foo(float* a, float* b, int n) {
    std::copy(std::execution::unseq, a, a+n, b);
}

サンプル 2

このサンプルは fill_n の並列化バージョンを呼び出します。

#include <vector>
#include "pstl/execution"
#include "pstl/algorithm"

int main()
{
    std::vector<int> data(10000000);
    std::fill_n(std::execution::par_unseq, data.begin(), data.size(), -1);  // Fill the vector with -1

    return 0;
}

実装されているアルゴリズム

Parallel STL は、次の表にリストされているアルゴリズムでのみ、前述のすべての実行ポリシーをサポートします。その他の C++ 標準ライブラリー・アルゴリズムにポリシー引数を追加すると、シーケンシャル実行になります。

アルゴリズム

cppreference.com のアルゴリズム・ページ (英語)

adjacent_find

http://en.cppreference.com/w/cpp/algorithm/adjacent_find

all_of

http://en.cppreference.com/w/cpp/algorithm/all_any_none_of

any_of

http://en.cppreference.com/w/cpp/algorithm/all_any_none_of

copy

http://en.cppreference.com/w/cpp/algorithm/copy

copy_if

http://en.cppreference.com/w/cpp/algorithm/copy

copy_n

http://en.cppreference.com/w/cpp/algorithm/copy_n

count

http://en.cppreference.com/w/cpp/algorithm/count

count_if

http://en.cppreference.com/w/cpp/algorithm/count

equal

http://en.cppreference.com/w/cpp/algorithm/equal

exclusive_scan

http://en.cppreference.com/w/cpp/algorithm/exclusive_scan

fill

http://en.cppreference.com/w/cpp/algorithm/fill

fill_n

http://en.cppreference.com/w/cpp/algorithm/fill_n

find

http://en.cppreference.com/w/cpp/algorithm/find

find_if

http://en.cppreference.com/w/cpp/algorithm/find

find_if_not

http://en.cppreference.com/w/cpp/algorithm/find

for_each

http://en.cppreference.com/w/cpp/algorithm/for_each

for_each_n

http://en.cppreference.com/w/cpp/algorithm/for_each_n

generate

http://en.cppreference.com/w/cpp/algorithm/generate

generate_n

http://en.cppreference.com/w/cpp/algorithm/generate_n

inclusive_scan

http://en.cppreference.com/w/cpp/algorithm/inclusive_scan

is_sorted

http://en.cppreference.com/w/cpp/algorithm/is_sorted

is_sorted_until

http://en.cppreference.com/w/cpp/algorithm/is_sorted_until

none_of

http://en.cppreference.com/w/cpp/algorithm/all_any_none_of

reduce

http://en.cppreference.com/w/cpp/algorithm/reduce

remove_copy

http://en.cppreference.com/w/cpp/algorithm/remove_copy

remove_copy_if

http://en.cppreference.com/w/cpp/algorithm/remove_copy

sort

http://en.cppreference.com/w/cpp/algorithm/sort

stable_sort

http://en.cppreference.com/w/cpp/algorithm/stable_sort

transform

http://en.cppreference.com/w/cpp/algorithm/transform

transform_exclusive_scan

http://en.cppreference.com/w/cpp/algorithm/transform_exclusive_scan

transform_inclusive_scan

http://en.cppreference.com/w/cpp/algorithm/transform_inclusive_scan

transform_reduce

http://en.cppreference.com/w/cpp/algorithm/transform_reduce

unique_copy

http://en.cppreference.com/w/cpp/algorithm/unique_copy

既知の制限

ランダムアクセス・イテレーターが提供される場合、並列実行とベクトル実行は前述のアルゴリズムのサブセットでのみサポートされ、残りの実行はシリアルのままです。