Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

C++ マルチスレッド 入門

51,857 views

Published on

KMC 関東例会での講座の資料 (by @nojima)

Published in: Technology
  • Hi there! I just wanted to share a list of sites that helped me a lot during my studies: .................................................................................................................................... www.EssayWrite.best - Write an essay .................................................................................................................................... www.LitReview.xyz - Summary of books .................................................................................................................................... www.Coursework.best - Online coursework .................................................................................................................................... www.Dissertations.me - proquest dissertations .................................................................................................................................... www.ReMovie.club - Movies reviews .................................................................................................................................... www.WebSlides.vip - Best powerpoint presentations .................................................................................................................................... www.WritePaper.info - Write a research paper .................................................................................................................................... www.EddyHelp.com - Homework help online .................................................................................................................................... www.MyResumeHelp.net - Professional resume writing service .................................................................................................................................. www.HelpWriting.net - Help with writing any papers ......................................................................................................................................... Save so as not to lose
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Dating direct: ♥♥♥ http://bit.ly/369VOVb ♥♥♥
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Follow the link, new dating source: ❶❶❶ http://bit.ly/369VOVb ❶❶❶
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • DOWNLOAD THAT BOOKS/FILE INTO AVAILABLE FORMAT - (Unlimited) ......................................................................................................................... ......................................................................................................................... Download FULL PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... .............. Browse by Genre Available eBooks ......................................................................................................................... accessibility Books Library allowing access to top content, including thousands of title from favorite author, plus the ability to read or download a huge selection of books for your pc or smartphone within minutes Christian, Classics, Comics, Contemporary, Cookbooks, Art, Biography, Business, Chick Lit, Children's, Manga, Memoir, Music, Science, Science Fiction, Self Help, History, Horror, Humor And Comedy, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance,
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • ACCESS that WEBSITE Over for All Ebooks (Unlimited) ......................................................................................................................... DOWNLOAD FULL PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... DOWNLOAD FULL EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download Full PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download EPUB Ebook here { http://bit.ly/2m6jJ5M }
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

C++ マルチスレッド 入門

  1. 1. C++ マルチスレッド 入門 KMC 関東例会 (@ Cookpad) 2015/04/24 野島 裕輔
  2. 2. 自己紹介 • 野島 裕輔 • KMC ID: nojima • Github: nojima • Twitter: nojima • サイボウズ株式会社でインフラ開発をやっています。 • nginx のパッチを書いて DoS 対策したり SSL セッションキャッシュをホスト間で共有したり • サーバクラスタの管理ツールを作ったり • 矢印が判定エァリアに重なるタァーイミングで左のパァーノゥを踏むッ!!
  3. 3. ムーアの法則 「集積回路上のトランジスタ数は18ヶ月ごとに倍になる。」 → プログラマが何もしなくてもソフトウェアは高速になっていった。 http://ja.wikipedia.org/wiki/%E3%83%A0%E3%83%BC%E3%82%A2%E3%81%AE%E6%B3%95%E5%89%87
  4. 4. しかし…
  5. 5. CPU の周波数は 3 GHz ぐらいで頭打ちに CPU DB: Recording Microprocessor History - ACM Queue https://queue.acm.org/detail.cfm?id=2181798
  6. 6. ポラックの法則 • 「プロセッサの性能は、そのダイサイズの平方根に比例する」 • Intel のフレッド・ポラックさんの経験則 • 性能を2倍にするには、ダイサイズを4倍にしないといけない。 • それならば、単一のコアの性能は増やさずにコアを4つ積め ば4倍の性能になるのでは? CPU のマルチコア化がトレンドに
  7. 7. The Free Lunch Is Over タダ飯の時代は終わった Herb Sutter (Microsoft の偉い人)
  8. 8. マルチコア時代のソフトウェア • ハードウェアの進化を享受するためには、複数コアを上手く利 用できるようにプログラムを書く必要がある。 • マルチプロセス化 • データを共有する必要がないか、少数のデータしか共有しなくていい 場合は複数のプロセスを立ち上げて、プロセス間通信などでデータを 共有するのが安全。 • マルチスレッド化 • 多くのデータを共有する場合は、メモリ空間を共有して複数スレッドを 実行するのが効率的。 • 今回の講座ではマルチスレッドを扱う。
  9. 9. C++ とマルチスレッド • C++11 から言語にマルチスレッドのサポートが入った。 • これにより環境依存のライブラリを利用しなくても、 C++ の標準ライブラリだけでマルチスレッドなプログラムが 書けるようになった。 • しかも、わりと使い勝手がよい。
  10. 10. これさえあれば、だれでも簡単に マルチスレッドプログラミングが……!!
  11. 11. これさえあれば、だれでも簡単に マルチスレッドプログラミングが……!! \______ _______________________/ ○ O モワモワ o ∧_∧! ハッ! / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ___( ゜∀゜)_ < という夢を見たんだ | 〃( つ つ | \________ |\ ⌒⌒⌒⌒⌒⌒\ | \^ ⌒ ⌒ \ \ |⌒⌒⌒⌒⌒⌒ | \|________|
  12. 12. 現実 • マルチスレッドプログラミングは罠だらけ。 • とりあえず罠を知ろう。
  13. 13. 読み書きの競合 2つのスレッドで x++ を実行 read x calc x + 1 write x x = 0 x = 1 read x calc x + 1 write xx = 2
  14. 14. 読み書きの競合 2つのスレッドで x++ を実行 read x calc x + 1 write x x = 0 x = 1 read x calc x + 1 write xx = 1
  15. 15. 読み書きの競合 2つのスレッドで x++ を実行 read x calc x + 1 write x x = 0 x = 1 read x calc x + 1 write xx = 1 タイミングによって最終結果が異なる
  16. 16. キャッシュによる一貫性の破れ Core 1 Core 2 キャッシュ メモリ x = 100; y = 200; cout << y << endl; cout << x << endl; y 0 x 0
  17. 17. キャッシュによる一貫性の破れ Core 1 Core 2 キャッシュ メモリ x = 100; y = 200; cout << y << endl; cout << x << endl; y 0 x 0 x 100
  18. 18. キャッシュによる一貫性の破れ Core 1 Core 2 キャッシュ メモリ x = 100; y = 200; cout << y << endl; cout << x << endl; y 0 x 0 x 100 y 200
  19. 19. キャッシュによる一貫性の破れ Core 1 Core 2 キャッシュ メモリ x = 100; y = 200; cout << y << endl; cout << x << endl; y 0 x 0 x 100 y 200 y 200
  20. 20. キャッシュによる一貫性の破れ Core 1 Core 2 キャッシュ メモリ x = 100; y = 200; cout << y << endl; cout << x << endl; y 0 x 0 x 100 y 200 y 200 y 200
  21. 21. キャッシュによる一貫性の破れ Core 1 Core 2 キャッシュ メモリ x = 100; y = 200; cout << y << endl; cout << x << endl; y 0 x 0 x 100 y 200 y 200 y 200 x 0
  22. 22. キャッシュによる一貫性の破れ Core 1 Core 2 キャッシュ メモリ x = 100; y = 200; cout << y << endl; cout << x << endl; y 0 x 0 x 100 y 200 y 200 y 200 x 0 x → y という順番で書き込んだはずなのに、y の値しか読めていない!!
  23. 23. コンパイラによる最適化 // Thread 1 ans = complex_computation(); done = true; // Thread 2 while (!done) /* busy loop */; cout << ans << endl; bool done = false; // global variable double ans = 0.0; // global variable
  24. 24. コンパイラによる最適化 // Thread 1 ans = complex_computation(); done = true; // Thread 2 while (!done) /* busy loop */; cout << ans << endl; コンパイラ先生 「ループ一周ごとに !done を 評価するのは無駄では?」 bool done = false; // global variable double ans = 0.0; // global variable
  25. 25. コンパイラによる最適化 // Thread 1 ans = complex_computation(); done = true; // Thread 2 if (!done) { while (true) /* busy loop */; } cout << ans << endl; コンパイラ先生 「最適化しといたで!!!」 bool done = false; // global variable double ans = 0.0; // global variable
  26. 26. コンパイラによる最適化 // Thread 1 ans = complex_computation(); done = true; // Thread 2 if (!done) { while (true) /* busy loop */; } cout << ans << endl; コンパイラ先生 「最適化しといたで!!!」 無限ループ!! bool done = false; // global variable double ans = 0.0; // global variable
  27. 27. 我々はいったいどうすればいいのか? • 間違った解決策: • 全ての変数に volatile をつける • volatile にデータ競合を防ぐ力はない • 全ての変数を atomic テンプレートでくるむ • できない • プログラム全体を lock で囲う • マルチスレッドとは… • コードを書いて神に祈る • 日頃の行いに依る http://nonylene.net/blog/2014-12/dendengu.html
  28. 28. 我々はいったいどうすればいいのか? • 間違った解決策: • 全ての変数に volatile をつける • volatile にデータ競合を防ぐ力はない • 全ての変数を atomic テンプレートでくるむ • できない • プログラム全体を lock で囲う • マルチスレッドとは… • コードを書いて神に祈る • 日頃の行いに依る http://nonylene.net/blog/2014-12/dendengu.html まずはメモリモデルを知ろう
  29. 29. この講座は • マルチスレッドプログラミングを安全に行うために 必要なメモリモデルの概念を紹介する • メモリモデルとは、メモリへの読み書きがどういう性質を満たすべきかを 記述したもの。 • 時間の制約上、色々端折ってたり誤魔化したりしているので注意。
  30. 30. 用語 • オブジェクト • 規格上の定義は region of storage. • メモリ上に固有の領域を持っている存在。 • 変数とか配列の要素とか一時オブジェクトとか。 • 評価 • 式の値を計算したり、式の副作用を発動させたりすること。 • 一つの式が複数回評価されたり、一回も評価されなかったりする。 • 例えば、以下のプログラムの場合、x = 42 は 10 回評価される。 • for (int i = 0; i < 10; ++i) x = 42;
  31. 31. happens before • 評価と評価の間には、happens before 関係という半順序関 係が定義されている。 • 直感的には、A happens before B とは、B が始まる前に必ず A が完了していることを表す。 • happens before は半順序関係なので、グラフ的には DAG で表現できる。 x = 0 x y = 1 z = 3 y
  32. 32. happens before • 同じスレッド上で実行される評価の間には、 自明な順序で happens before が定義される。 • たまに例外もあるが… • 異なるスレッド上で実行される評価の間には、 特別なことがない限り happens before は成り立たない。 • どういう場合に成り立つかは後述。
  33. 33. data race • 2 つの評価 A, B が以下の4条件を満たすとき、 プログラムに data race があるという。 1. A, B が同一の非アトミックオブジェクトに対する操作 2. A, B の少なくとも一方が書き込み操作 3. A happens before B でない 4. B happens before A でない • プログラムに data race があるとき、undefined behavior が起こる。
  34. 34. data race bool done = false; // global variable double ans = 0.0; // global variable // Thread 1 ans = complex_computation(); done = true; // Thread 2 while (!done) /* busy loop */; cout << ans << endl;  同一の非アトミックオブジェクトに対する操作  一方は書き込み操作  お互いに happens before でない
  35. 35. data race bool done = false; // global variable double ans = 0.0; // global variable // Thread 1 ans = complex_computation(); done = true; // Thread 2 while (!done) /* busy loop */; cout << ans << endl;  同一の非アトミックオブジェクトに対する操作  一方は書き込み操作  お互いに happens before でない undefined behavior
  36. 36. atomic • アトミックオブジェクトは data race を起こさない特別な オブジェクト。 • std::atomic<T> で T 型のアトミック版が手に入る。 • 例: • std::atomic<int> // アトミックな int • std::atomic<void*> // アトミックな void* • なんでもアトミックにできるわけではなく、T は trivially copyable なものに制限されている。 • つまり、T はユーザ定義のコピーコンストラクタ、ムーブコンストラクタ、 代入演算子、デストラクタを持てない。
  37. 37. atomic std::atomic<int> x; // 0 で初期化される x.store(42); // x に 42 を書き込む cout << x.load() << endl; // x の値を読む x.fetch_add(1); // 値を 1 増やす cout << x.load() << endl; // 43 が出力される // x == y ならば x に 100 を代入 (いわゆるCAS) int y = 43; x.compare_exchange_strong(y, 100);
  38. 38. atomic と happens before アトミックオブジェクト M に対する書き込み操作 W と M に対する読み込み操作 R があるとする。 もし R が W の書き込んだ値を読んだとすると、 W happens before R が成り立つ。 (このとき W synchronizes with R という) ※ memory_order が relaxed や consume でない場合
  39. 39. atomic と happens before std::atomic<bool> done = false; // global variable double ans = 0.0; // global variable // Thread 1 ans = complex_computation(); done.store(true); // Thread 2 while (!done.load()) /* busy loop */; cout << ans << endl; • atomic 変数を使うことにより、done に関する data race を解消。 • done の store-load により、ans の書き込みと ans の読み込みの 間にも happens before 関係が入る。
  40. 40. atomic と happens before ans = complex_computation(); done.store(true); done.load() done.load() done.load() done.load() cout << ans << endl; 同一スレッドなので happens before synchronize!! 同一スレッドなので happens before
  41. 41. atomic と happens before ans = complex_computation(); done.store(true); done.load() done.load() done.load() done.load() cout << ans << endl; 同一スレッドなので happens before synchronize!! 同一スレッドなので happens before
  42. 42. mutex • std::atomic<T> では、一回の store や fetch_add など をアトミックに実行できる。 • しかし、実際にはもっと複雑な計算をアトミックにやらないとい けない場合が多い。 • std::mutex を使えば、lock() してから unlock() する までの間を排他処理することができる。 • つまり、lock() から unlock() までの間を複数のスレッドが同時に実 行しないことを保証できる。
  43. 43. mutex map<string, string> pages; // global variable mutex pages_mutex; // global variable void save_page(const string& url) { result = (url にアクセスして内容を取得); pages_mutex.lock(); // 例外安全性はとりあえず置いておく pages[url] = result; pages_mutex.unlock(); } int main() { // 並列にウェブサイトをクロール thread t1(save_page, "http://foo"); thread t2(save_page, "http://bar"); t1.join(); t2.join(); }
  44. 44. ロックしてるから安全? string* pHello = nullptr; // global variable mutex mtx; // global variable // singleton() は複数のスレッドから並列に呼ばれる void singleton() { // double-checked locking pattern のつもり if (pHello == nullptr) { mtx.lock(); // とりあえず例外安全性には目をつぶる if (pHello == nullptr) pHello = new string("Hello"); mtx.unlock(); } // シングルトンなオブジェクトへのアクセス cout << *pHello << endl; }
  45. 45. ロックしてるから安全? string* pHello = nullptr; // global variable mutex mtx; // global variable // singleton() は複数のスレッドから並列に呼ばれる void singleton() { // double-checked locking pattern のつもり if (pHello == nullptr) { mtx.lock(); // とりあえず例外安全性には目をつぶる if (pHello == nullptr) pHello = new string("Hello"); mtx.unlock(); } // シングルトンなオブジェクトへのアクセス cout << *pHello << endl; } undefined behavior
  46. 46. mutex と happens before • 単一の mutex に対する lock(), unlock() はある全順序 S に従って起こる。 • スレッドA, B, C, D があるときに、スレッド A から見て C → D の順で ロックを取ったように見えたとしたら、B から見ても C → D の順でロック を取ったように見える。 • U をある mutex に対する unlock 操作、 L を同じ mutex に対する lock 操作とする。 このとき、S の上で U < L ならば U happens before L である。
  47. 47. ロックしてるから安全?(再掲) string* pHello = nullptr; // global variable mutex mtx; // global variable // singleton() は複数のスレッドから並列に呼ばれる void singleton() { // double-checked locking pattern のつもり if (pHello == nullptr) { mtx.lock(); // とりあえず例外安全性には目をつぶる if (pHello == nullptr) pHello = new string("Hello"); mtx.unlock(); } // シングルトンなオブジェクトへのアクセス cout << *pHello << endl; } undefined behavior
  48. 48. happens before 関係を図示すると… pHello == nullptr mtx.lock() pHello == nullptr pHello = new string(..) mtx.unlock() cout << *pHello << endl pHello == nullptr cout << *pHello << endl
  49. 49. happens before 関係を図示すると… pHello == nullptr mtx.lock() pHello == nullptr pHello = new string(..) mtx.unlock() cout << *pHello << endl pHello == nullptr cout << *pHello << endl
  50. 50. happens before 関係を図示すると… pHello == nullptr mtx.lock() pHello == nullptr pHello = new string(..) mtx.unlock() cout << *pHello << endl pHello == nullptr cout << *pHello << endl 実際、pHello が読めた としても、pHello が指す 先が読めるとは限らない。
  51. 51. 直し方 直し方はいろいろある。 1. pHello の型を atomic<string*> にする。 • こうすると、 pHello.store(new string(...)) と pHello.load() == nullptr の間に happens before 関係が入る。 2. double-checked locking pattern を使わずに、いきなり lock する。 • mtx.unlock() happens before mtx.lock() となるので OK。 3. Mayers' singleton を使う。
  52. 52. まとめ • 非アトミックなオブジェクトに対して、互いに happens before 関係にない読み書きが発生すると data race。 • 同じスレッド上の評価は自明な順番で happens before 関係 が入る。 • 同一のアトミックオブジェクトに対する store と load は条件を 満たすと happens before 関係を作る。 • 同一の mutex に対する unlock と lock は条件を満たすと happens before 関係を作る。
  53. 53. 参考文献 • Working Draft, Standard for Programming Language C++ https://github.com/cplusplus/draft • cppreference.com http://cppreference.com/

×