最終更新日時(UTC):
が更新

履歴 編集

class
<execution>

std::execution::parallel_scheduler(C++26)

namespace std::execution {
  class parallel_scheduler { unspecified };
}

概要

parallel_schedulerは、実行制御ライブラリ上でタスクの並列実行を可能とする並列Schedulerである。

parallel_schedulerはグローバルなスレッドプール(実行リソース)に関連付けられ、schedule操作により得られるSenderはスレッドプールに属する任意のスレッド(実行エージェント)上で実行される。

下記のSenderアルゴリズムに対してカスタマイズ実装を提供することで、タスクの一括(bulk)実行をスレッドプールを利用したタスク並列(parallel)実行に変換する。

execution::parallel_scheduler_replacement 名前空間で定義されるインタフェースを介して、スレッドプール実装をユーザ定義の並列Schedulerバックエンドに置き換えることもできる。

クラス仕様

parallel_schedulerschedulerのモデルである。

説明用のschparallel_scheduler型のオブジェクト、schptrと関連付けられるときBACKEND-OF(sch)*ptrとする。

get_forward_progress_guarantee(sch)forward_progress_guarantee::parallelを返す。

説明用のsch2parallel_scheduler型のオブジェクトとしたとき、BACKEND-OF(sch)BACKEND-OF(sch2)が同一オブジェクトを指す場合に限って、2つのオブジェクトschsch2は等しい。

rcvrReceiverとしたとき、基底Bを持つrcvrのプロキシは下記を満たすB型の左辺値rとなる。

  • r.set_value()は、set_value(std::move(rcvr))と同じ効果。
  • r.set_error(e)は、eexception_ptrとして、set_error(std::move(rcvr), std::move(e))と同じ効果。
  • r.set_stopped()は、set_stopped(std::move(rcvr))と同じ効果。

プロキシrに対する事前確保バックエンドストレージ(preallocated backend storage)は、span<byte>型のオブジェクトsであり、rに対してset_valueset_errorset_stoppedいずれかが呼び出されるまで範囲sは有効かつ上書き可能である。

get_domain(sch)は、下記と等価な説明専用の型parallel-scheduler-domainの式を返す。

struct parallel-scheduler-domain {
  template<sender-for<bulk_chunked_t> Sndr, queryable Env>
  static constexpr decltype(auto)
    transform_sender(set_value_t, Sndr&& sndr, const Env& env) const noexcept {
      return see below;
    }
  template<sender-for<bulk_unchunked_t> Sndr, queryable Env>
  static constexpr decltype(auto)
    transform_sender(set_value_t, Sndr&& sndr, const Env& env) const noexcept {
      return see below;
    }
};

上記transform_senderの引数sndrに対して、説明用の変数child, pol, shape, fを下記の通り宣言する。

auto& [_, data, child] = sndr;
auto& [pol, shape, f] = data;

説明用のpを下記とする。

scheduleアルゴリズム

説明用のbBACKEND-OF(sch)sndrschedule(sch)が返すオブジェクト、rcvrReceiverとする。rcvrsndr接続(connect)され、結果のOperation State開始(start)されたとき、

  • sndrが値完了するならば、b.schedule(r, s)が呼ばれる。このとき、
  • 他の全ての完了操作は、変更なしに転送される。

bulk_chunkedアルゴリズム

タグbulk_chunked_tSenderを受け付けるtransform_senderオーバーロードは、Receiverrcvr接続(connect)され結果のOperation State開始(start)されたとき、下記動作を行うSenderを返す。

  • childが値valsで値完了するならば、argsvalsを指す左辺値式のパックとして、b.schedule_bulk_chunked(p ? shape : 1, r, s)が呼ばれる。このとき、
    • rは基底クラスparallel_scheduler_replacement::bulk_item_receiver_proxyを持つrcvrのプロキシであり、インデックスi, jに対してr.execute(i, j)ptrueのときf(i, j, args...)、そうでないときはf(0, shape, args...)と等価な効果を持つ。かつ
    • srに対する事前確保バックエンドストレージである。
  • 他の全ての完了操作は、変更なしに転送される。

bulk_unchunkedアルゴリズム

タグbulk_unchunked_tSenderを受け付けるtransform_senderオーバーロードは、Receiverrcvr接続(connect)され結果のOperation State開始(start)されたとき、下記動作を行うSenderを返す。

  • childが値valsで値完了するならば、argsvalsを指す左辺値式のパックとして、b.schedule_bulk_unchunked(p ? shape : 1, r, s)が呼ばれる。このとき、
    • rは基底クラスparallel_scheduler_replacement::bulk_item_receiver_proxyを持つrcvrのプロキシであり、インデックスiに対してr.execute(i, i + 1)ptrueのときf(i, args...)、そうでないときはfor (decltype(shape) i = 0; i < shape; i++) { f(i, args...); }と等価な効果を持つ。かつ
    • srに対する事前確保バックエンドストレージである。
  • 他の全ての完了操作は、変更なしに転送される。

#include <concepts>
#include <execution>
namespace ex = std::execution;

int main()
{
  ex::scheduler auto sch = ex::get_parallel_scheduler();
  static_assert(std::same_as<decltype(sch), ex::parallel_scheduler>);
}

出力

バージョン

言語

  • C++26

処理系

関連項目

参照