SlideShare una empresa de Scribd logo
1 de 22
Descargar para leer sin conexión
Effective Modern C++Effective Modern C++勉強会勉強会 #8#8
2015/08/19
@simizut22
⾮非同期性が必須なら⾮非同期性が必須なら std::launch::asyncstd::launch::async を指定すを指定す
るる
item36item36
asyncasync のの 22 種類の種類の overloadoverload
default
task のpolicy 指
定
async(F&&, Args&&...);
async(std::launch, F&&, Args&&...);
std::launchstd::launch
enum class lauch : unspecified {
async = unspecified
, deferred = unspecified
implementation-defined
};
scoped enum を⽤用いて規定されている bitmask type
拡張 policy 及びそのbitmask の実装は,実装系に許可
されている
std::launchstd::launch とと std::asyncstd::async
lauch::async
lauch::deferred
異なるスレッドで⾮非同期実⾏行を指定する
呼び出しスレッドと同期実⾏行を指定する
launch::deferred 指定時
get /wait が呼ばれたときに task が実⾏行される
実⾏行されないかもしれない(thread と違って問題ない)
注釈について注釈について
auto f = std::async( std::launch::deferred,
[]{ std::cout << "wait..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
return 0; });
std::shared_future< int > sf = f.share();
auto sf2 = sf;
sf.wait();
std::cout << sf2.get() << std::endl;
sf2 に対して wait/get 呼ぶ前から
sf2 の参照する shared_state は結果を持っている
(shared_state に関しては item38 参照)
defaultdefault とと policypolicy 指定指定
std::async( f );
std::async( std::launch::async | std::launch::deferred,
f);
default の実⾏行は bit を async/deferred 両⽅方⽴立てるの
と同じ意味
つまり,次の2つは全く同じ挙動をする
このときの挙動は実装依存
とある
“ Note: If this policy is specified together with other policies, such as
when using a policy value of launch::async |launch::deferred,
implementations should defer invocation or the selection of the policy
when no more concurrency can be effectively exploited.
実装依存!!
とはいえ [futures.async] の note に
> 実⾏行ポリシーを launch::async |launch::deferred と指定したときに
は, 並列性を効果的に利⽤用できない場合,どちらのポリシーに従うか
を決めるのを遅延するか,task の実⾏行を遅延する(deferred を選択す
る)べき
というところ
並列性が⼗十分に取れるときの動きは書かれていない(未規定??)
http://melpon.org/wandbox/permlink/PiUr8pUjjDmA7C5V
std::cout << "hardware_concurrency = " << std::thread::hardware_concurrency()<<std::endl;
using namespace std::literals;
std::vector< std::future< void > > fvec(100);
std::generate( std::begin(fvec), std::end(fvec),
[]{ return
std::async([]{ std::this_thread::sleep_for(1s);
std::cout << std::this_thread::get_id() <<std::endl;});});
std::for_each( std::begin(fvec),
std::end(fvec),
[](auto&& x){ x.wait();} );
なお,gcc は 6 系で default の挙動が変わる模様??
6 より前と後で,次の code の結果がかなり違う
にあるように,
同期/⾮非同期的に動くかを library の実装が決めてくれる
Bartos Mileski ⽒氏のblog
default policydefault policy の良さの良さ
terminate called after throwing an instance of 'std::system_error'
what(): Resource temporarily unavailable
中⽌止
さらに,resource のこういう error ⾒見なくてよくな
る
defaultdefault ,困ります,困ります(>_<)(>_<)
auto fut = srd::async( f ); // use default policy
s, t, u という名前に次のようにスレッドを束縛する
s f が実⾏行されるスレッド
t async が呼ばれるスレッド
u get/wait を呼ぶスレッド
例えば次みたいな code を考えると...
void f() {
std::cout << "s: " << std::this_thread::get_id() << std::endl; // s
}
std::future< void > g() {
std::cout << "t: " << std::this_thread::get_id() << std::endl; // t
auto fut = std::async( f );
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
return fut;
}
int main() {
std::cout << "u:" << std::this_thread::get_id() << std::endl; // u
std::async( g ).get().get();
return 0;
}
http://melpon.org/wandbox/permlink/a7oHldjWHTEGA1Yq
VisualStudio2015 で build した結果
あれ,あれ,ss とと tt が⼀一致しているが⼀一致している!!(!!(環境でまちまち環境でまちまち))
defaultdefault ,困ります,困ります(>_<)(>_<)
s != t かわからない (∵ deferred になるかもしれない
s != u かわからない
そもそもget/wait されないかもしれない
s f が実⾏行されるスレッド
t async が呼ばれるスレッド
u get/wait を呼ぶスレッド
*再掲
defaultdefault ,困ります,困ります(>_<)(>_<)
thread-local storage(TLS) を使ってると問題出る
thread_local int i = 0;
void fun(int left, int right ) {
if (left < right-1) {
auto f1 = std::async( fun, left, (left + right) / 2);
auto f2 = std::async( fun, (left + right)/2, right);
f1.wait();
f2.wait();
}
else {
++i;
}
}
int main() {
fun(0, 10);
std::cout << i << std::endl;
}
どのスレッドで fun が呼ばれるかで結果が変わる
http://melpon.org/wandbox/permlink/lcd7FOlnXfsUBH7T
defaultdefault ,困ります,困ります(>_<)(>_<)
次の code を考える
void f () { std::this_thread::sleep( 1s ); // std::chrono::seconds(1)
auto fut = std::async(f);
while (fut.wait_for(100ms) // std::chrono::milliseconds(1)
!=
std::future_status::ready) {
/* something */
}
wait_for/untilwait_for/until とと future_statusfuture_status
deferred 関数をもつ future_status::deferred
準備完了(値が返せる) future_status::ready
準備中 future_status::timeout
wait_for/until の返値は shared_stateにより以下で決まる
while (fut.wait_for(100ms)
!=
std::future_status::ready) {
}
deferred と schedule されたら,
いくら待っても ready にならない!!!! bug だっ
bug fixbug fix
future が deferred かどうか直接聞く⽅方法はない
wait の返値で future_status::deferred と⾔言うのはある
wait は deferred のとき何もしない
template< typename R >
inline
bool is_defered( std::future< R > const& f) {
return f.wait_for(0s) == std::future_status::deferred;
}
// shared_future も まったく同じなので割愛
auto fut = std::async(f);
if (is_defered(fut)) {
/* hogehoge */
}
else {
while (fut.wait_for(100ms)) {
/* fugafuga */
}
}
ということなので, check を作る
asyncasync でデフォルトが使える条件でデフォルトが使える条件
1. call/wait を呼ぶ thread と並列であってもなくてもよい
2. どの thread の TLS を読み書きするか問わない(またはTLS は使わな
い)
3. get/wait をどの path でも呼んでいる.
または実⾏行されなくても問題ない保証がある
4. wait_for/until を使っているならば deferred も考慮している
であれば async をdefault で実⾏行してもよ
い.
どれか⼀一つでも⽋欠けるなら default ,やめよう
async policyasync policy を使うを使う APIAPI ⽤用意する⽤用意する......
template< typename F, typename ...Args >
inline
std::future< typename std::result_of< F(Args...) >::type >
reallyAsync( F&& f, Args&&... args) {
return std::async(std::launch::async,
std::forward< F >(f),
std::forward< Args >(args)...);
}
c++11 version1
(c++11では)間違ってないけど...
C++14 だと若干型の宣⾔言が修正されている
template< typename F, typename ...Args >
inline
std::future< std::result_of_t< std::decay_t< F >(std::decay_t< Args >...) > >
// ^^^^^^^^^^^^ ^^^^^^^^^^^^ // decay がついてる!
reallyAsync( F&& f, Args&&... args) {
return std::async(std::launch::async,
std::forward< F >(f),
std::forward< Args >(args)...);
}
愚直に書き換え愚直に書き換え
c++14 version1
返値の型書くの,ツライ(-_-;)
修正版修正版(C++14 version)(C++14 version)
template< typename F, typename ...Args >
inline
auto
reallyAsync( F&& f, Args&&... args) {
return std::async(std::launch::async,
std::forward< F >(f),
std::forward< Args >(args)...);
}
すっきり (^^)/
* C++11 で trailing return type 使っても,やっぱりだるい...
things to rememberthings to remember
async の default policy は task の同期/⾮非同期実⾏行のど
ちらにもなり得る
その柔軟性のために
- TLS 使⽤用時に不確かさを起こし得る(毎回違う結果と
か
- task が実⾏行されないかもしれない
- time-out の wait に対して program の変更が必要
などの影響をもたらす
確実に⾮非同期実⾏行にしたければ std::launch::async を(明
⽰示的に)指定する

Más contenido relacionado

La actualidad más candente

Effective modern c++ 5
Effective modern c++ 5Effective modern c++ 5
Effective modern c++ 5uchan_nos
 
Boost.勉強会 #21 札幌「C++1zにstring_viewが導入されてうれしいので紹介します」
Boost.勉強会 #21 札幌「C++1zにstring_viewが導入されてうれしいので紹介します」Boost.勉強会 #21 札幌「C++1zにstring_viewが導入されてうれしいので紹介します」
Boost.勉強会 #21 札幌「C++1zにstring_viewが導入されてうれしいので紹介します」Hiro H.
 
Boost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
Boost.勉強会#19東京 Effective Modern C++とC++ Core GuidelinesBoost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
Boost.勉強会#19東京 Effective Modern C++とC++ Core GuidelinesShintarou Okada
 
Effective Modern C++勉強会#4 Item 17, 18資料
Effective Modern C++勉強会#4 Item 17, 18資料Effective Modern C++勉強会#4 Item 17, 18資料
Effective Modern C++勉強会#4 Item 17, 18資料Ryo Igarashi
 
Effective Modern C++ Item 9 and 10
Effective Modern C++ Item 9 and 10Effective Modern C++ Item 9 and 10
Effective Modern C++ Item 9 and 10uchan_nos
 
Effective Modern C++ 勉強会 Item 22
Effective Modern C++ 勉強会 Item 22Effective Modern C++ 勉強会 Item 22
Effective Modern C++ 勉強会 Item 22Keisuke Fukuda
 
Constexpr 中3女子テクニック
Constexpr 中3女子テクニックConstexpr 中3女子テクニック
Constexpr 中3女子テクニックGenya Murakami
 
BoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうかBoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうかYuki Miyatake
 
Effective Modern C++ 勉強会 Item26
Effective Modern C++ 勉強会 Item26Effective Modern C++ 勉強会 Item26
Effective Modern C++ 勉強会 Item26Akihiro Nishimura
 
C++のビルド高速化について
C++のビルド高速化についてC++のビルド高速化について
C++のビルド高速化についてAimingStudy
 
C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会Akihiko Matuura
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチンyohhoy
 
Visual C++で使えるC++11
Visual C++で使えるC++11Visual C++で使えるC++11
Visual C++で使えるC++11nekko1119
 
C++のライブラリを簡単に眺めてみよう
C++のライブラリを簡単に眺めてみようC++のライブラリを簡単に眺めてみよう
C++のライブラリを簡単に眺めてみようHiro H.
 
Consulを頑張って理解する
Consulを頑張って理解するConsulを頑張って理解する
Consulを頑張って理解するMasakazu Watanabe
 
C#や.NET Frameworkがやっていること
C#や.NET FrameworkがやっていることC#や.NET Frameworkがやっていること
C#や.NET Frameworkがやっていること信之 岩永
 
クロージャデザインパターン
クロージャデザインパターンクロージャデザインパターン
クロージャデザインパターンMoriharu Ohzu
 
入門Transducers
入門Transducers入門Transducers
入門Transducerssohta
 
Java開発の強力な相棒として今すぐ使えるGroovy
Java開発の強力な相棒として今すぐ使えるGroovyJava開発の強力な相棒として今すぐ使えるGroovy
Java開発の強力な相棒として今すぐ使えるGroovyYasuharu Nakano
 

La actualidad más candente (20)

Effective modern c++ 5
Effective modern c++ 5Effective modern c++ 5
Effective modern c++ 5
 
Boost.勉強会 #21 札幌「C++1zにstring_viewが導入されてうれしいので紹介します」
Boost.勉強会 #21 札幌「C++1zにstring_viewが導入されてうれしいので紹介します」Boost.勉強会 #21 札幌「C++1zにstring_viewが導入されてうれしいので紹介します」
Boost.勉強会 #21 札幌「C++1zにstring_viewが導入されてうれしいので紹介します」
 
Boost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
Boost.勉強会#19東京 Effective Modern C++とC++ Core GuidelinesBoost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
Boost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
 
Effective Modern C++勉強会#4 Item 17, 18資料
Effective Modern C++勉強会#4 Item 17, 18資料Effective Modern C++勉強会#4 Item 17, 18資料
Effective Modern C++勉強会#4 Item 17, 18資料
 
Effective Modern C++ Item 9 and 10
Effective Modern C++ Item 9 and 10Effective Modern C++ Item 9 and 10
Effective Modern C++ Item 9 and 10
 
Effective Modern C++ 勉強会 Item 22
Effective Modern C++ 勉強会 Item 22Effective Modern C++ 勉強会 Item 22
Effective Modern C++ 勉強会 Item 22
 
Constexpr 中3女子テクニック
Constexpr 中3女子テクニックConstexpr 中3女子テクニック
Constexpr 中3女子テクニック
 
BoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうかBoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうか
 
Effective Modern C++ 勉強会 Item26
Effective Modern C++ 勉強会 Item26Effective Modern C++ 勉強会 Item26
Effective Modern C++ 勉強会 Item26
 
C++のビルド高速化について
C++のビルド高速化についてC++のビルド高速化について
C++のビルド高速化について
 
Emcjp item21
Emcjp item21Emcjp item21
Emcjp item21
 
C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
 
Visual C++で使えるC++11
Visual C++で使えるC++11Visual C++で使えるC++11
Visual C++で使えるC++11
 
C++のライブラリを簡単に眺めてみよう
C++のライブラリを簡単に眺めてみようC++のライブラリを簡単に眺めてみよう
C++のライブラリを簡単に眺めてみよう
 
Consulを頑張って理解する
Consulを頑張って理解するConsulを頑張って理解する
Consulを頑張って理解する
 
C#や.NET Frameworkがやっていること
C#や.NET FrameworkがやっていることC#や.NET Frameworkがやっていること
C#や.NET Frameworkがやっていること
 
クロージャデザインパターン
クロージャデザインパターンクロージャデザインパターン
クロージャデザインパターン
 
入門Transducers
入門Transducers入門Transducers
入門Transducers
 
Java開発の強力な相棒として今すぐ使えるGroovy
Java開発の強力な相棒として今すぐ使えるGroovyJava開発の強力な相棒として今すぐ使えるGroovy
Java開発の強力な相棒として今すぐ使えるGroovy
 

Destacado

topology of musical data
topology of musical datatopology of musical data
topology of musical dataTatsuki SHIMIZU
 
Magnitude ~ extend the Euler Characteristics via Möbius Inversion ~
Magnitude ~ extend the Euler Characteristics via  Möbius Inversion ~Magnitude ~ extend the Euler Characteristics via  Möbius Inversion ~
Magnitude ~ extend the Euler Characteristics via Möbius Inversion ~Tatsuki SHIMIZU
 
introductino to persistent homology and topological data analysis
introductino to persistent homology and topological data analysisintroductino to persistent homology and topological data analysis
introductino to persistent homology and topological data analysisTatsuki SHIMIZU
 
情報幾何学の基礎 第2章 4.5
情報幾何学の基礎 第2章 4.5情報幾何学の基礎 第2章 4.5
情報幾何学の基礎 第2章 4.5Tatsuki SHIMIZU
 
Effective Modern C++ 読書会 Item 35
Effective Modern C++ 読書会 Item 35Effective Modern C++ 読書会 Item 35
Effective Modern C++ 読書会 Item 35Keisuke Fukuda
 

Destacado (9)

topology of musical data
topology of musical datatopology of musical data
topology of musical data
 
Magnitude ~ extend the Euler Characteristics via Möbius Inversion ~
Magnitude ~ extend the Euler Characteristics via  Möbius Inversion ~Magnitude ~ extend the Euler Characteristics via  Möbius Inversion ~
Magnitude ~ extend the Euler Characteristics via Möbius Inversion ~
 
TDA やら Night!!
TDA やら Night!!TDA やら Night!!
TDA やら Night!!
 
introductino to persistent homology and topological data analysis
introductino to persistent homology and topological data analysisintroductino to persistent homology and topological data analysis
introductino to persistent homology and topological data analysis
 
情報幾何学の基礎 第2章 4.5
情報幾何学の基礎 第2章 4.5情報幾何学の基礎 第2章 4.5
情報幾何学の基礎 第2章 4.5
 
Emcjp item33,34
Emcjp item33,34Emcjp item33,34
Emcjp item33,34
 
Effective Modern C++ 読書会 Item 35
Effective Modern C++ 読書会 Item 35Effective Modern C++ 読書会 Item 35
Effective Modern C++ 読書会 Item 35
 
Emcpp item41
Emcpp item41Emcpp item41
Emcpp item41
 
Emcpp item31
Emcpp item31Emcpp item31
Emcpp item31
 

Similar a effective modern c++ chapeter36

Continuation with Boost.Context
Continuation with Boost.ContextContinuation with Boost.Context
Continuation with Boost.ContextAkira Takahashi
 
今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 TipsTakaaki Suzuki
 
Kanazawa.js.Next
Kanazawa.js.NextKanazawa.js.Next
Kanazawa.js.Nextdynamis
 
initとプロセス再起動
initとプロセス再起動initとプロセス再起動
initとプロセス再起動Takashi Takizawa
 
Dive into RTS - another side
Dive into RTS - another sideDive into RTS - another side
Dive into RTS - another sideKiwamu Okabe
 
C++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みくださいC++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みくださいdigitalghost
 
Swift 2.0 で変わったところ「前編」 #cswift
Swift 2.0 で変わったところ「前編」 #cswiftSwift 2.0 で変わったところ「前編」 #cswift
Swift 2.0 で変わったところ「前編」 #cswiftTomohiro Kumagai
 
Flow.js
Flow.jsFlow.js
Flow.jsuupaa
 
Pub/Sub model, msm, and asio
Pub/Sub model, msm, and asioPub/Sub model, msm, and asio
Pub/Sub model, msm, and asioTakatoshi Kondo
 
ZFSのソースコードをチラ見してみる
ZFSのソースコードをチラ見してみるZFSのソースコードをチラ見してみる
ZFSのソースコードをチラ見してみるKoichi Suzuki
 
あんなテスト、こんなテスト(this and that about testing)
あんなテスト、こんなテスト(this and that about testing)あんなテスト、こんなテスト(this and that about testing)
あんなテスト、こんなテスト(this and that about testing)Takuya Tsuchida
 
Boost9 session
Boost9 sessionBoost9 session
Boost9 sessionfreedom404
 
Flutterを体験してみませんか
Flutterを体験してみませんかFlutterを体験してみませんか
Flutterを体験してみませんかcch-robo
 
SystemC Tutorial
SystemC TutorialSystemC Tutorial
SystemC Tutorialkocha2012
 
gen-class とバイトコード(第3回 gen-class 勉強会資料)
gen-class とバイトコード(第3回 gen-class 勉強会資料)gen-class とバイトコード(第3回 gen-class 勉強会資料)
gen-class とバイトコード(第3回 gen-class 勉強会資料)tnoda
 

Similar a effective modern c++ chapeter36 (20)

Continuation with Boost.Context
Continuation with Boost.ContextContinuation with Boost.Context
Continuation with Boost.Context
 
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
 
今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips
 
Kanazawa.js.Next
Kanazawa.js.NextKanazawa.js.Next
Kanazawa.js.Next
 
initとプロセス再起動
initとプロセス再起動initとプロセス再起動
initとプロセス再起動
 
Dive into RTS - another side
Dive into RTS - another sideDive into RTS - another side
Dive into RTS - another side
 
C++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みくださいC++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みください
 
Swift 2.0 で変わったところ「前編」 #cswift
Swift 2.0 で変わったところ「前編」 #cswiftSwift 2.0 で変わったところ「前編」 #cswift
Swift 2.0 で変わったところ「前編」 #cswift
 
Flow.js
Flow.jsFlow.js
Flow.js
 
Pub/Sub model, msm, and asio
Pub/Sub model, msm, and asioPub/Sub model, msm, and asio
Pub/Sub model, msm, and asio
 
ZFSのソースコードをチラ見してみる
ZFSのソースコードをチラ見してみるZFSのソースコードをチラ見してみる
ZFSのソースコードをチラ見してみる
 
あんなテスト、こんなテスト(this and that about testing)
あんなテスト、こんなテスト(this and that about testing)あんなテスト、こんなテスト(this and that about testing)
あんなテスト、こんなテスト(this and that about testing)
 
Improvement future api
Improvement future apiImprovement future api
Improvement future api
 
Boost9 session
Boost9 sessionBoost9 session
Boost9 session
 
Flutterを体験してみませんか
Flutterを体験してみませんかFlutterを体験してみませんか
Flutterを体験してみませんか
 
Effective Java 輪読会 項目66-68
Effective Java 輪読会 項目66-68Effective Java 輪読会 項目66-68
Effective Java 輪読会 項目66-68
 
Boost tour 1_44_0
Boost tour 1_44_0Boost tour 1_44_0
Boost tour 1_44_0
 
SystemC Tutorial
SystemC TutorialSystemC Tutorial
SystemC Tutorial
 
URLで遊ぼう
URLで遊ぼうURLで遊ぼう
URLで遊ぼう
 
gen-class とバイトコード(第3回 gen-class 勉強会資料)
gen-class とバイトコード(第3回 gen-class 勉強会資料)gen-class とバイトコード(第3回 gen-class 勉強会資料)
gen-class とバイトコード(第3回 gen-class 勉強会資料)
 

Más de Tatsuki SHIMIZU

Introduction to Persistence Theory
Introduction to Persistence TheoryIntroduction to Persistence Theory
Introduction to Persistence TheoryTatsuki SHIMIZU
 
エキゾチック球面ナイト(浮気編)~28 日周期の彼女たち~
エキゾチック球面ナイト(浮気編)~28 日周期の彼女たち~エキゾチック球面ナイト(浮気編)~28 日周期の彼女たち~
エキゾチック球面ナイト(浮気編)~28 日周期の彼女たち~Tatsuki SHIMIZU
 
Euler 標数は測度ですか??
Euler 標数は測度ですか??Euler 標数は測度ですか??
Euler 標数は測度ですか??Tatsuki SHIMIZU
 
Operad and Recognition Principle
Operad and Recognition PrincipleOperad and Recognition Principle
Operad and Recognition PrincipleTatsuki SHIMIZU
 
Introduction to Topological Data Analysis
Introduction to Topological Data AnalysisIntroduction to Topological Data Analysis
Introduction to Topological Data AnalysisTatsuki SHIMIZU
 
情報幾何の基礎輪読会 #1
情報幾何の基礎輪読会 #1情報幾何の基礎輪読会 #1
情報幾何の基礎輪読会 #1Tatsuki SHIMIZU
 
代数トポロジー入門
代数トポロジー入門代数トポロジー入門
代数トポロジー入門Tatsuki SHIMIZU
 

Más de Tatsuki SHIMIZU (13)

ロマ数16 simizut
ロマ数16 simizutロマ数16 simizut
ロマ数16 simizut
 
Introduction to Persistence Theory
Introduction to Persistence TheoryIntroduction to Persistence Theory
Introduction to Persistence Theory
 
エキゾチック球面ナイト(浮気編)~28 日周期の彼女たち~
エキゾチック球面ナイト(浮気編)~28 日周期の彼女たち~エキゾチック球面ナイト(浮気編)~28 日周期の彼女たち~
エキゾチック球面ナイト(浮気編)~28 日周期の彼女たち~
 
Practical topology
Practical topologyPractical topology
Practical topology
 
Euler 標数は測度ですか??
Euler 標数は測度ですか??Euler 標数は測度ですか??
Euler 標数は測度ですか??
 
Operad and Recognition Principle
Operad and Recognition PrincipleOperad and Recognition Principle
Operad and Recognition Principle
 
しかくのお勉強
しかくのお勉強しかくのお勉強
しかくのお勉強
 
Packing
PackingPacking
Packing
 
Introduction to Topological Data Analysis
Introduction to Topological Data AnalysisIntroduction to Topological Data Analysis
Introduction to Topological Data Analysis
 
Jules henri poincaré
Jules henri poincaréJules henri poincaré
Jules henri poincaré
 
情報幾何の基礎輪読会 #1
情報幾何の基礎輪読会 #1情報幾何の基礎輪読会 #1
情報幾何の基礎輪読会 #1
 
代数トポロジー入門
代数トポロジー入門代数トポロジー入門
代数トポロジー入門
 
Effective modern-c++#9
Effective modern-c++#9Effective modern-c++#9
Effective modern-c++#9
 

effective modern c++ chapeter36

  • 1. Effective Modern C++Effective Modern C++勉強会勉強会 #8#8 2015/08/19 @simizut22
  • 3. asyncasync のの 22 種類の種類の overloadoverload default task のpolicy 指 定 async(F&&, Args&&...); async(std::launch, F&&, Args&&...);
  • 4. std::launchstd::launch enum class lauch : unspecified { async = unspecified , deferred = unspecified implementation-defined }; scoped enum を⽤用いて規定されている bitmask type 拡張 policy 及びそのbitmask の実装は,実装系に許可 されている
  • 5. std::launchstd::launch とと std::asyncstd::async lauch::async lauch::deferred 異なるスレッドで⾮非同期実⾏行を指定する 呼び出しスレッドと同期実⾏行を指定する launch::deferred 指定時 get /wait が呼ばれたときに task が実⾏行される 実⾏行されないかもしれない(thread と違って問題ない)
  • 6. 注釈について注釈について auto f = std::async( std::launch::deferred, []{ std::cout << "wait..." << std::endl; std::this_thread::sleep_for(std::chrono::seconds(1)); return 0; }); std::shared_future< int > sf = f.share(); auto sf2 = sf; sf.wait(); std::cout << sf2.get() << std::endl; sf2 に対して wait/get 呼ぶ前から sf2 の参照する shared_state は結果を持っている (shared_state に関しては item38 参照)
  • 7. defaultdefault とと policypolicy 指定指定 std::async( f ); std::async( std::launch::async | std::launch::deferred, f); default の実⾏行は bit を async/deferred 両⽅方⽴立てるの と同じ意味 つまり,次の2つは全く同じ挙動をする このときの挙動は実装依存
  • 8. とある “ Note: If this policy is specified together with other policies, such as when using a policy value of launch::async |launch::deferred, implementations should defer invocation or the selection of the policy when no more concurrency can be effectively exploited. 実装依存!! とはいえ [futures.async] の note に > 実⾏行ポリシーを launch::async |launch::deferred と指定したときに は, 並列性を効果的に利⽤用できない場合,どちらのポリシーに従うか を決めるのを遅延するか,task の実⾏行を遅延する(deferred を選択す る)べき というところ 並列性が⼗十分に取れるときの動きは書かれていない(未規定??)
  • 9. http://melpon.org/wandbox/permlink/PiUr8pUjjDmA7C5V std::cout << "hardware_concurrency = " << std::thread::hardware_concurrency()<<std::endl; using namespace std::literals; std::vector< std::future< void > > fvec(100); std::generate( std::begin(fvec), std::end(fvec), []{ return std::async([]{ std::this_thread::sleep_for(1s); std::cout << std::this_thread::get_id() <<std::endl;});}); std::for_each( std::begin(fvec), std::end(fvec), [](auto&& x){ x.wait();} ); なお,gcc は 6 系で default の挙動が変わる模様?? 6 より前と後で,次の code の結果がかなり違う
  • 10. にあるように, 同期/⾮非同期的に動くかを library の実装が決めてくれる Bartos Mileski ⽒氏のblog default policydefault policy の良さの良さ terminate called after throwing an instance of 'std::system_error' what(): Resource temporarily unavailable 中⽌止 さらに,resource のこういう error ⾒見なくてよくな る
  • 11. defaultdefault ,困ります,困ります(>_<)(>_<) auto fut = srd::async( f ); // use default policy s, t, u という名前に次のようにスレッドを束縛する s f が実⾏行されるスレッド t async が呼ばれるスレッド u get/wait を呼ぶスレッド 例えば次みたいな code を考えると...
  • 12. void f() { std::cout << "s: " << std::this_thread::get_id() << std::endl; // s } std::future< void > g() { std::cout << "t: " << std::this_thread::get_id() << std::endl; // t auto fut = std::async( f ); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ return fut; } int main() { std::cout << "u:" << std::this_thread::get_id() << std::endl; // u std::async( g ).get().get(); return 0; } http://melpon.org/wandbox/permlink/a7oHldjWHTEGA1Yq VisualStudio2015 で build した結果 あれ,あれ,ss とと tt が⼀一致しているが⼀一致している!!(!!(環境でまちまち環境でまちまち))
  • 13. defaultdefault ,困ります,困ります(>_<)(>_<) s != t かわからない (∵ deferred になるかもしれない s != u かわからない そもそもget/wait されないかもしれない s f が実⾏行されるスレッド t async が呼ばれるスレッド u get/wait を呼ぶスレッド *再掲
  • 14. defaultdefault ,困ります,困ります(>_<)(>_<) thread-local storage(TLS) を使ってると問題出る thread_local int i = 0; void fun(int left, int right ) { if (left < right-1) { auto f1 = std::async( fun, left, (left + right) / 2); auto f2 = std::async( fun, (left + right)/2, right); f1.wait(); f2.wait(); } else { ++i; } } int main() { fun(0, 10); std::cout << i << std::endl; } どのスレッドで fun が呼ばれるかで結果が変わる http://melpon.org/wandbox/permlink/lcd7FOlnXfsUBH7T
  • 15. defaultdefault ,困ります,困ります(>_<)(>_<) 次の code を考える void f () { std::this_thread::sleep( 1s ); // std::chrono::seconds(1) auto fut = std::async(f); while (fut.wait_for(100ms) // std::chrono::milliseconds(1) != std::future_status::ready) { /* something */ }
  • 16. wait_for/untilwait_for/until とと future_statusfuture_status deferred 関数をもつ future_status::deferred 準備完了(値が返せる) future_status::ready 準備中 future_status::timeout wait_for/until の返値は shared_stateにより以下で決まる while (fut.wait_for(100ms) != std::future_status::ready) { } deferred と schedule されたら, いくら待っても ready にならない!!!! bug だっ
  • 17. bug fixbug fix future が deferred かどうか直接聞く⽅方法はない wait の返値で future_status::deferred と⾔言うのはある wait は deferred のとき何もしない template< typename R > inline bool is_defered( std::future< R > const& f) { return f.wait_for(0s) == std::future_status::deferred; } // shared_future も まったく同じなので割愛 auto fut = std::async(f); if (is_defered(fut)) { /* hogehoge */ } else { while (fut.wait_for(100ms)) { /* fugafuga */ } } ということなので, check を作る
  • 18. asyncasync でデフォルトが使える条件でデフォルトが使える条件 1. call/wait を呼ぶ thread と並列であってもなくてもよい 2. どの thread の TLS を読み書きするか問わない(またはTLS は使わな い) 3. get/wait をどの path でも呼んでいる. または実⾏行されなくても問題ない保証がある 4. wait_for/until を使っているならば deferred も考慮している であれば async をdefault で実⾏行してもよ い. どれか⼀一つでも⽋欠けるなら default ,やめよう
  • 19. async policyasync policy を使うを使う APIAPI ⽤用意する⽤用意する...... template< typename F, typename ...Args > inline std::future< typename std::result_of< F(Args...) >::type > reallyAsync( F&& f, Args&&... args) { return std::async(std::launch::async, std::forward< F >(f), std::forward< Args >(args)...); } c++11 version1 (c++11では)間違ってないけど... C++14 だと若干型の宣⾔言が修正されている
  • 20. template< typename F, typename ...Args > inline std::future< std::result_of_t< std::decay_t< F >(std::decay_t< Args >...) > > // ^^^^^^^^^^^^ ^^^^^^^^^^^^ // decay がついてる! reallyAsync( F&& f, Args&&... args) { return std::async(std::launch::async, std::forward< F >(f), std::forward< Args >(args)...); } 愚直に書き換え愚直に書き換え c++14 version1 返値の型書くの,ツライ(-_-;)
  • 21. 修正版修正版(C++14 version)(C++14 version) template< typename F, typename ...Args > inline auto reallyAsync( F&& f, Args&&... args) { return std::async(std::launch::async, std::forward< F >(f), std::forward< Args >(args)...); } すっきり (^^)/ * C++11 で trailing return type 使っても,やっぱりだるい...
  • 22. things to rememberthings to remember async の default policy は task の同期/⾮非同期実⾏行のど ちらにもなり得る その柔軟性のために - TLS 使⽤用時に不確かさを起こし得る(毎回違う結果と か - task が実⾏行されないかもしれない - time-out の wait に対して program の変更が必要 などの影響をもたらす 確実に⾮非同期実⾏行にしたければ std::launch::async を(明 ⽰示的に)指定する