Presentation is loading. Please wait.

Presentation is loading. Please wait.

稲葉 一浩 (kinaba@google.com) SC22/C++WG May 2015 Review for N4399: “Working Draft, Technical Specification for C++ Extensions for Concurrency” 稲葉 一浩 (kinaba@google.com)

Similar presentations


Presentation on theme: "稲葉 一浩 (kinaba@google.com) SC22/C++WG May 2015 Review for N4399: “Working Draft, Technical Specification for C++ Extensions for Concurrency” 稲葉 一浩 (kinaba@google.com)"— Presentation transcript:

1 稲葉 一浩 (kinaba@google.com) SC22/C++WG May 2015
Review for N4399: “Working Draft, Technical Specification for C++ Extensions for Concurrency” 稲葉 一浩 SC22/C++WG May 2015

2 参考資料 レポジトリ 関連 Proposal TS Draft
関連 Proposal ...  N3784 : “Improvements to std::future<T> and Related APIs” ...  N3785 : “Executors and Schedulers” ...  N4392 : “C++ Latches and Barriers” ...  N4162 : “Atomic Smart Pointers” TS Draft N3970 : May (≒N N3785) Editor note: N3971, Comments: N4032, N4048 N4107 : Jul (-= N3785) Editor note: N4108, Revisions: N4123, N4313 N4399 : Apr (+= N4204, N4162) Editor Note: N4400

3 N4399 の内容 3本立て Improvements to std::future<T> and Related APIs
Latches and Barriers Atomic Smart Pointers

4 おさらい: futureとは 「どこかで実行された計算の結果がそのうち入る」行き先を表す
std::future<int> ft = std::async([](){ // 非同期にこの関数を実行 return 42; }); if (ft.wait_for(std::chrono::seconds(1)) == std::future_status::ready) { int v = ft.get(); // 42 }

5 1. Improvements to std::future<T>
以下のメンバ関数を追加 future(future<future<R>>&& rhs); see below then(F&& func); bool is_ready() const noexcept; 以下の関数を追加 see below when_all(InputIterator begin, InputIterator end); see below when_all(Futures&&... futures); see below when_any(InputIterator begin, InputIterator end); see below when_any(Futures&&... futures); future<decay_t<T>> make_ready_future(T&& value); future<T> make_execeptional_future(exception_ptr ex); 複数のfuture(やfutureを作る計算)を組み合わせて新しいfutureを作るユーティリティ関数群

6 1. Improvements to std::future<T>
以下のメンバ関数を追加 future(future<future<R>>&& rhs); see below then(F&& func); bool is_ready() const noexcept; 以下の関数を追加 see below when_all(InputIterator begin, InputIterator end); see below when_all(Futures&&... futures); see below when_any(InputIterator begin, InputIterator end); see below when_any(Futures&&... futures); future<decay_t<T>> make_ready_future(T&& value); future<T> make_execeptional_future(exception_ptr ex); C++11 ドラフト段階では一度 提案されていた関数。復活

7 1. Improvements to std::future<T>
以下のメンバ関数を追加 future(future<future<R>>&& rhs); see below then(F&& func); bool is_ready() const noexcept; 以下の関数を追加 see below when_all(InputIterator begin, InputIterator end); see below when_all(Futures&&... futures); see below when_any(InputIterator begin, InputIterator end); see below when_any(Futures&&... futures); future<decay_t<T>> make_ready_future(T&& value); future<T> make_execeptional_future(exception_ptr ex);

8 1. Improvements to std::future<T>
future<T> ft = ...; ft.then(func); 「ft の値が取り出し可能になったら func(ft) を実行してその値を返す future」 を即座に返す func は future<T> を引数にとる。 T ではない。 Haskell の Monad (引数型はT) や ECMAScript6 の Promise (引数型はT、Exception時のためにもう一つ関数オブジェクトを渡す) とは型が違う funcの返値型が future<R> なら then の型も future<R> funcの返値型がそれ以外の R なら then の型は future<R> (前者が “implicit unwrapping” と呼ばれる特殊規則。future<future<R>> にはならない)

9 1. Improvements to std::future<T>
future<T> ft = make_ready_future(v); 「値 v が既に取り出し可能な状態になっている future」 T を future<T> に変換する future(future<future<R>>&& rhs); future<future<T>> を future<T> に変換する rhsとrhs.get()がreadyならready。get()はrhs.get()の結果になる

10 1. Improvements to std::future<T>
以下のメンバ関数を追加 future(future<future<R>>&& rhs); see below then(F&& func); bool is_ready() const noexcept; 以下の関数を追加 see below when_all(InputIterator begin, InputIterator end); see below when_all(Futures&&... futures); see below when_any(InputIterator begin, InputIterator end); see below when_any(Futures&&... futures); future<decay_t<T>> make_ready_future(T&& value); future<T> make_execeptional_future(exception_ptr ex);

11 1. Improvements to std::future<T>
future<vector< typename iterator_traits<InputIterator>::value_type >> when_all(InputIterator, InputIterator); future<tuple<decay_t<Futures>...>> when_all(Futures&&...); 「引数に渡した全てのfutureがreadyになったらreadyになるfuture」を返す。返値はfutureのvector/tupleのfuture。 readyになったら引数のfutureがmoveされる

12 1. Improvements to std::future<T>
template<class Sequence> struct when_any_result { size_t index; Sequence futures; }; future<when_any_result<vector<typename iterator_traits<InputIterator>::value_type>>> when_any(InputIterator, InputIterator); future<when_any_result<tuple<decay_t<Futures>...>>> when_any(Futures&&... futures); 引数どれか一つ以上がreadyになったらreadyになるfutureを返す 引数が0個なら即座にreadyとなる 返値は「引数全部のSequenceと発火したindex」という意図だと思われるが、現在のdraftではindexについて何も触れられていない (ミス?)

13 気になったところ then や when_all や when_any に引数として渡したfutureは、関数から返った時点で無効になっている “Postcondition” の項を見るとわかる “Effects” の項を見ると、新しく作った future が ready になった後に move が行われることは書かれているが、関数呼び出し時については言及されていない

14 2. Latches and Barriers スレッド間同期プリミティブ latch barrier flex_barrier
最初に同期ポイントに入った n 個のスレッドが “participating thread ” となる 各スレッドは基本的に 「1 減らして待つ」 ことができる カウンタが 0 になったら待ちスレッド全て実行再開 latch Single-use (一度カウンタが 0 になったら destruct しかできない) barrier Single-use ではない (カウンタが0になったあと戻る) arrive_and_drop() という操作で participating thread から抜けられる flex_barrier コンストラクタに関数オブジェクト (ptrdiff_t ()) を指定できる。 カウンタ 0 になった時に呼ばれる。 -1 を返すと barrier と同じ動作。それ以外の値を返すと新しい participating thread 集合のサイズとして扱われる

15 class latch { public: explicit latch(ptrdiff_t count); void count_down_and_wait(); void count_down(ptrdiff_t n); bool is_ready() const noexcept; void wait() const; }; 少し前までの proposal では arrive_and_wait() だった。 count_down(n) に合わせて改名? class barrier { public: explicit barrier(ptrdiff_t num_threads); void arrive_and_wait(); void arrive_and_drop(); }; class flex_barrier { public: template <class F> flex_barrier(ptrdiff_t num_threads, F completion); explicit flex_barrier(ptrdiff_t num_threads); void arrive_and_wait(); void arrive_and_drop(); };

16 3. Atomic Smart Pointers atomic_shared_ptr<T>
atomic_weak_ptr<T> shared_ptr<T> と weak_ptr<T> の atomic版 “The behavior of all operations is as specified in C++14 §29.6.5, unless stated otherwise.” “When any operation on an atomic_shared_ptr or atomic_weak_ptr causes an object to be destroyed or memory to be deallocated, that destruction or deallocation shall be sequenced after the changes to the atomic object's state.” atomic_unique_ptr<T> は無い(なぜ?)


Download ppt "稲葉 一浩 (kinaba@google.com) SC22/C++WG May 2015 Review for N4399: “Working Draft, Technical Specification for C++ Extensions for Concurrency” 稲葉 一浩 (kinaba@google.com)"

Similar presentations


Ads by Google