Namespaces
Variants

std::execution:: bulk, std::execution:: bulk_chunked, std::execution:: bulk_unchunked

From cppreference.net
定義先ヘッダ <execution>
std :: execution :: sender

auto bulk ( std :: execution :: sender auto input,
std:: integral auto size,
auto && policy,
std:: invocable < decltype ( size ) ,

/*values-sent-by*/ ( input ) ... > function ) ;
(1) (C++26以降)
std :: execution :: sender

auto bulk_chunked ( std :: execution :: sender auto input,
std:: integral auto size,
auto && policy,
std:: invocable < decltype ( size ) , decltype ( size ) ,

/*values-sent-by*/ ( input ) ... > function2 ) ;
(2) (C++26以降)
std :: execution :: sender

auto bulk_unchunked ( std :: execution :: sender auto input,
std:: integral auto size,
std:: invocable < decltype ( size ) , decltype ( size ) ,

/*values-sent-by*/ ( input ) ... > function ) ;
(3) (C++26以降)

目次

パラメータ

input - 一度実行されると関数が実行される値群を送信するsender
policy - execution policy function / function2 に付与される
function - 範囲 [ 0 , size ) 内の各インデックスに対して呼び出される呼び出し可能オブジェクト。入力senderによって生成された値も渡される
function2 - function と同様だが、インデックスのペア ( b , e ) で呼び出される( b < e )。範囲 [ [ 0 , size ) 内の各インデックス i に対して、 b <= i < e となるように function2 が正確に1回呼び出される

戻り値

入力 sender によって記述されるタスクグラフを記述する sender を返し、範囲 [ 0 , size ) 内のインデックスと入力 sender から送信された値を引数として、提供された関数を呼び出す追加ノードを付加します。

function / function2 は、返されたsenderが開始されるまで実行を開始しないことが保証されています。

エラー補完

すべてのエラーは input によって渡され、転送されます。

さらに、送信者は以下の内容を含む std::exception_ptr エラーで完了することが許可されています:

  • function によってスローされるあらゆる例外
  • std::bad_alloc 実装が要求されたリソースの割り当てに失敗した場合
  • std::runtime_error から派生した例外(例:実行コンテキストから呼び出し元へ例外を伝播できない場合など、その他の内部エラー)

キャンセレーション

カスタマイズされていない std::execution::bulk std::execution::bulk_chunk および std::execution::bulk_unchunked は、 input からの停止完了シグナルを転送します。これらは停止完了シグナルを生成する追加のメカニズムを提供しません。

注記

std::execution::bulk および std::execution::bulk_chunked を呼び出す際、 function / function2 の異なる呼び出しが同一の実行エージェント上で発生する可能性があります。

std::execution::bulk_unchunked を呼び出す際、 function の異なる呼び出しは、異なる実行エージェント上で発生しなければなりません。

std::execution::bulk のデフォルト実装は std::execution::bulk_chunked に基づいています。 std::execution::bulk をカスタマイズすることは可能ですが、 ほとんどの場合 std::execution::bulk_chunked のみが カスタマイズされると予想されます。

std::execution::bulk および std::execution::bulk_chunked のカスタマイズがない場合、 std::execution::bulk std::execution::bulk_chunk の動作は function を逐次実行するものであり、特に有用ではありません。実装では、異なるスケジューラ上で std::execution::bulk std::execution::bulk_chunked を実行することをより有用にするカスタマイズが提供されることが期待されます。

std::execution::bulk_unchunked は、 function が異なる呼び出し間で依存関係を持つ可能性があり、並行進行保証(並列進行保証では不十分)が必要な場合に使用されることを意図しています。 std::execution::bulk_unchunked をサイズ1000で実行すると、1000個の実行エージェント(例えばスレッド)が並行して実行される必要があります。

std::execution::bulk_unchunked は実行ポリシーを必要としません。これは既に function が並行して実行可能であることが期待されているためです。

execution::bulk の使用可能性。

std::vector<double> x;
std::vector<double> y;
//...
sender auto process_elements
    = just(get_coefficient())
    | bulk(x.size(), [&](size_t i, double a)
    {
        y[i] = a * x[i] + y[i];
    });
// process_elementsは、係数`a`を取得する関数を呼び出し、それを用いて
// 各`i`(範囲[0, x.size()))に対して
//   y[i] = a * x[i] + y[i]
// を実行する処理を記述します

execution::bulk_chunked の使用可能性。

std::vector<std::uint32_t> data = ...;
std::atomic<std::uint32_t> sum{0};
sender auto s = bulk_chunked(just(), par, 100000,
    [&sum, &data](int begin, int end)
    {
        auto partial_sum = std::accumulate(data.begin() + begin, data.begin() + end, 0U);
        sum.fetch_add(partial_sum);
    });
// atomicオブジェクトは100000回触れられることはなく、bulk()よりも高速に実行されます