STL <algorithm> または <numeric> ヘッダーで定義されている関数は従来のブロッキングです。インテル® oneDPL は、非ブロッキング動作を含む非同期アルゴリズムを提供して C++17 並列アルゴリズムの機能を拡張します。この試験的な機能を利用して、依存関係チェーンの構築、アルゴリズム呼び出しのインターリーブ、データ並列 C++ (DPC++) および SYCL* カーネルとの相互運用性により、並列の制御フローを表現できます。
非同期アルゴリズムの現在の実装は DPC++ 実行ポリシーでのみ利用できます。以下の機能はすべて、oneapi::dpl::experimental 名前空間で利用できます。
次の非同期アルゴリズムが現在サポートされています。
copy_async
fill_async
for_each_async
reduce_async
sort_async
inclusive_scan_async
exclusive_scan_async
transform_async
transform_reduce_async
transform_inclusive_scan_async
transform_exclusive_scan_async
上記でリストされているすべてのインターフェイスは C++17 STL アルゴリズムのサブセットで、対応する名前 (reduce、sort、その他) にサフィックス _async を追加したものです。動作とシグネチャーは、C++17 STL アルゴリズムをオーバーラップします。次の点が変更されます。
実行をブロックしません。
任意の数のイベント (0 を含む) を最後の引数として指定し、入力の依存関係を表現できます。
完了に wait および結果に get を使用できる future 形式のオブジェクトを返します。
非同期アルゴリズムから返される future 形式のオブジェクトの型は不定です。次のメンバー関数があります。
get() は結果を返します。
wait() は結果が利用可能になるまで待ちます。
返されたオブジェクトがデバイスポリシーを含むアルゴリズムの結果の場合は、sycl::event に変換できます。アルゴリズムが割り当てるリソース (一時記憶域など) の存続期間は、返されたオブジェクトの存続期間になります。
次のユーティリティー関数を利用できます。
wait_for_all(…) は、sycl::event に変換可能な任意の数のオブジェクトの準備が完了するまで待ちます。
#include <oneapi/dpl/execution>
#include <oneapi/dpl/async>
#include <CL/sycl.hpp>
int main() {
using namespace oneapi;
{
/* 単純な依存関係チェーンを構築して計算: バッファーをフィル -> 変換 -> レデュース */
sycl::buffer<int> a{10};
auto fut1 = dpl::experimental::fill_async(dpl::execution::dpcpp_default,
dpl::begin(a),dpl::end(a),7);
auto fut2 = dpl::experimental::transform_async(dpl::execution::dpcpp_default,
dpl::begin(a),dpl::end(a),dpl::begin(a),
[&](const int& x){return x + 1; },fut1);
auto ret_val = dpl::experimental::reduce_async(dpl::execution::dpcpp_default,
dpl::begin(a),dpl::end(a),fut1,fut2).get();
}
return 0;
}