753 Views
October 09, 24
スライド概要
C#の高速化入門 Write by 森理 麟 非同期勉強会
Myself 森理 麟(@moririring) 職業:ゲームプログラマ HP : moririringのHP ツール : VagrantWin ←NEW! Microsoft MVP for Visual C#(2013.01 –) 2
My Community VSハッカソン倶楽部 + Visual Studio勉強会 C++テンプレート完全ガイド読 書会 Unityクリエイターズ IT英語勉強会 ぼちぼちぼっち開発 3
アジェンタ はじめに キーワード説明 プロセス スレッド 同期/非同期 コア 高速化 ターンアラウンドタイム スループット レスポンスタイム おわりに 4
first はじめに 5
僕がC#を始めたのは非同期プ ログラムを組みたかったから です。 はじめに 6
もっとも当時の僕は非同期と いう言葉は知りませんでした。 はじめに 7
動き出してからも止めたい。 そのためにはスレッドを使え ば良いのかな?でした。 はじめに 8
ただあまり詳しくない僕はマ ルチスレッドは高速化するた めの手法だと思っていました。 はじめに 9
非同期?高速化?マルチス レッド?はじめにこの当たり のキーワードを説明します。 はじめにの方が長い? はじめに 10
Process プロセス 11
プロセスとは実行しているプ ログラムの単位 プロセス 12
実行中のプロセスはタスクマ ネージャで確認出来る プロセス 13
プロセスは実行に必要なもの をまとめて格納するコンテナ プロセス 14
プロセスはタスクとかジョブ とも言う。タスクマネージャ というぐらいなので。 プロセス 15
C#プログラマとしては他の 実行ファイルを起動する時に Processを使う。超使う。 プロセス Process.Start("notepad.exe"); 16
Thread スレッド 17
スレッドとはプロセスの最小 の実行単位(因みにThreadは 糸のこと) スレッド 18
1つのプロセスが複数のス レッドを持つことが出来る。 これをマルチスレッドという。 スレッド 引用:++C++; // 未確認飛行 C マルチスレッド (http://ufcpp.net/study/csharp/sp_thread.html) 19
マルチスレッドは同時に処理 を実行出来る スレッド 引用:連載.NETマルチスレッド・プログラミング入門 (http://www.atmarkit.co.jp/ait/articles/0503/12/news025.html) 20
スレッドが集まってプロセス を構成する。プロセスもス レッドの一種。原子と分子、フォルダとファ イルのようなニュアンス。 スレッド 21
マルチプロセスも同じように 同時に実行できる スレッド 引用:組み込み分野における「マルチプロセッサ」とは ―― 多 機能・低消費電力の要求にこたえるための技術的要素と課題 (http://www.kumikomi.net/archives/2005/09/15multic.php?page=13) 22
違いはメモリ。プロセス間で はメモリは共有されない。ス レッド間では共有される。 スレッド 引用:連載.NETマルチスレッド・プログラミング入門 (http://www.atmarkit.co.jp/ait/articles/0503/12/news025.html) 23
まとめ プロセスはプログラムの実行 単位 スレッドはプロセス内に作ら れる処理の単位 1つのプロセスは1以上のス レッドを持つ スレッドもプロセスも複数持 てて、同時に実行できる 24
synchronous/ asynchronous 同期/非同期 25
プログラムの処理には同期と 非同期がある 非同期 26
処理をして結果が返ってくる まで待つのは同期。リレーは 同期。 非同期 27
処理を待たずに次の処理を実 行するのが非同期。玉入れは 非同期。 非同期 28
スレッドと同期、非同期は直 接は関係ない 非同期 29
しかしマルチスレッドは、ス レッド間が常に非同期。 非同期 引用:++C++; // 未確認飛行 C マルチスレッド (http://ufcpp.net/study/csharp/sp_thread.html) 30
つまりマルチスレッドは非同 期プログラムと親和性が高い 非同期 31
Core コア 32
コアとはCPUの中心部分であ り、実際に処理を行うところ コア 33
スレッドやプロセスはコアを 複数使用できる。マルチコア コア マルチスレッドとマルチタスクの違い (http://www.ni.com/white-paper/6424/ja/ ) 34
但しコアが一つでも、マルチ スレッドは可能。どうやる か? コア マルチスレッドとマルチタスクの違い (http://www.ni.com/white-paper/6424/ja/ ) 35
こう コア 36
マルチスレッドにしても処理 が速くなるとは限らない。む しろ遅くなることもある。 コア 37
シングルコアマルチスレッドは 並行処理、マルチコアマルチス レッドは並列処理。 コア 並行と並列について-並行コンピューティング技法-を読んで (http://www.m-tea.info/2011/03/concurrent-parallel-01.html) 38
まとめ プロセス、スレッド 同期、非同期 コア 並列、並行 ↓ マルチスレッドによる非同期 マルチコアによる並列処理 39
高速化
僕は高速化って「地球にやさ しい」ぐらい矛盾した言葉だ と思っています。 高速化 41
高速化 だってCPUは本来超高速です。 3GHzのCPUなら1秒間に30億回動 きます。 そこにプログラマがプログラム で負荷をかけまくって、1万回の ループで10万回の計算をさせた りして遅くします。 そうやって自分で遅くさせた CPUを、自分で遅くなくするの が高速化です。 42
turnaround time ターンアラウンドタイム 43
ターンアラウンドタイムとは 処理にかかる総時間のこと ターンアラウ ンドタイム 44
最初の高速化はターンアラン ドタイムの短縮 ターンアラウ ンドタイム 45
この高速化で最も重要なのが 計測 ターンアラウ ンドタイム 46
人間の感覚で速い遅いを判断 しては駄目 ターンアラウ ンドタイム 47
ストップウォッチを使って ちゃんと計測しよう ターンアラウ ンドタイム 48
C#でもストップウォッチ ターンアラウ ンドタイム var sw = Stopwatch.StartNew(); ShallowWork(); Console.WriteLine(sw.Elapsed); sw.Reset(); sw.Start(); DeepWork(); Console.WriteLine(sw.Elapsed); sw.Stop(); //00:00:00.0026507 //00:00:05.0886134 但し計測だけならストップウォッチよりプロファイラーの方が便利。(指摘によ り加筆。Thanks to kkamegawa) 49
大体はパレートの法則(90:10の 法則)が成り立つ ターンアラウ ンドタイム ヴィルフレド・パレート 50
ターンアラウ ンドタイム 10%を絞り込めたら、そこの部分 を高速化 IOアクセスの回数を減らしたり、 アルゴリズムを見直したり、事 前に計算してメモリに乗せたり。 C#なら16byte以下のclassをstruct にしたり、キャストが重いので asを使ったり(次ページに削除 理由) 、文字列の連携には StringBuilderを使ったり 51
前ページの取 り消し理由 「キャストが重いのでasを使 う」と書いた所、適当ではない との指摘を受ける。(Thanks to isishizuka!) 例外が発生するケースではキャ ストよりasを使った方が高速化 だけど、10%に絞り込んだ時に キャストをasに直すというのは 適当ではないため(100%確実に 型変換ができる場合はキャスト の方が高速)取り消しました。 52
ターンアラウ ンドタイム 奇抜なテクニックで速くなる ことはあまりないかも 地味で手間はかかるが、トラ イアンドエラーを繰り返す 学問には王道しかない ↑引用:森博嗣著「喜嶋先生の静かな世界」 53
ターンアラウ ンドタイム 同じ場所が再度遅くなること もよくある 計測結果は実際に動いている 環境に表示したり、ログを残 したり見える化すると良い 54
throughput スループット 55
スループットとは時間当たり で処理出来る量のこと。 スループット 56
次の高速化はスループッドの 増加 スループット 57
スループットを増やすにはコ アを増やすこと。 スループット 58
8分かかったものを4人で処理 すれば2分になる。仕事量が8 分であることには変わりない。 スループット 59
シングルコアでの並行処理で は速くならない。マルチコア での並列処理をする スループット 60
マルチコアプログラムを初め て組んだ時僕はとても驚きま した。 スループット 61
地味で手間のかかる高速化を していないのに、びっくりす るぐらい速くなった スループット 62
DEMO1
スループット
//通常for
for (int i = 0; i < 100; i++)
{
DeepWork();
}
//並列実行Paraller.For
Parallel.For(0, 100, i =>
{
DeepWork();
});
63
ただ、マルチコアプログラム は実際難しい点も多い。 スループット indexは順番不定 UIスレッド 排他制御 64
スループット 注意点はしっかり押さえよう! C# によるプログラミング入門 並列処理ライブラリ <- 岩永さ んとか この後のbiacさんのセッションで も…! MSDN - データとタスクの並列化 における注意点 並列コンピューティングとは何 か 65
ポイント ターンアラウンドタイムを減 らし、スループッドを増やせ ば速くなる しかし、速くなってもユー ザーは最終結果がファースト コンタクト 分かりやすく言うと1分を15秒 にしても皆(隣も!) 遅いと言う 66
Response time レスポンスタイム 67
レスポンスタイムとはアク ションに対してリアクション が返ってくるまでの時間。 レスポンスタ イム 68
最後の高速化が、レスポンス タイム、反応の速さの高速化。 レスポンスタ イム 69
レスポンスタイムを向上する にはマルチスレッドによる非 同期プログラミング レスポンスタ イム 70
非同期にするとフリーズし なくなる。DEMO2 レスポンスタ イム Task.Run(() => { for (int i = 0; i < 100; i++) { DeepWork(); } }); 71
しかし待つことは変わらない ケースが殆ど。 レスポンスタ イム 72
そこで、待つのが気にならな いコントロールでのUI/UX表現 が必須。 レスポンスタ イム 73
レスポンスタ イム コントロールの中で数少ない ボタンが持っているUI/UXの特 性があると思っています。 コンボボックスが次点? 74
アクションに対しての反応が 自分自身でない(ことが多い)の で即時でなくても待ちやすい。 レスポンスタ イム 75
レスポンスタ イム 他のコントロールはリアク ションが自分自身のため即座 でないと使いにくさを感じる。 DEMO3 76
レスポンスタ イム ボタン自体もリアクションと してEnabledをoffにすると分か りやすいし、誤動作防止。 DEMO4 77
レスポンスタ イム ボタン表示オフだけより何を しているのかを文字で書くだ けでも印象が違う。 DEMO5 78
特に重要なのが動き。動いてい るコントロールがあれば待ちや すい。 レスポンスタ イム Low Wai Yin's Portfolio:http://lwaiyin.wordpress.com/2011/02/25/2d-runanimation/ 79
コマンドラインでもキュレッ トが点滅しているので待てる レスポンスタ イム 80
ここで大問題。マルチスレッ ドにするとコントロールへの 書き込みが出来ない。 レスポンスタ イム 81
レスポンスタ イム 対応するにはWPFなら DispacherやWinFormなら Invoke。もしくは TaskSchedulerを使う DEMO6,7 82
var uiTask = TaskScheduler.FromCurrentSynchronizationContext(); await Task.Run(() => { for (int i = 0; i < 100; i++) { レスポンスタ イム DeepWork(); new Task(() => progressBar1.Value = i).Start(uiTask); } }); 83
レスポンスタ イム さらにプログレスバーにキャ ンセル処理。やっと最初の下 りの実現。 DEMO8 84
var uiTask = TaskScheduler.FromCurrentSynchronizationContext();
await Task.Run(() =>
{
for (int i = 0; i < 100; i++)
{
DeepWork();
レスポンスタ
イム
if (_cancelToken.IsCancellationRequested) break;
new Task(() => progressBar.Value = i).Start(uiTask);
}
});
private CancellationTokenSource _cancelToken = new
CancellationTokenSource();
private void cancelButton_Click(object sender, EventArgs e)
{
_cancelToken.Cancel();
}
85
ターンアラウンドタイムを減ら す。泥臭いけど王道。 まとめ スループットを増やす。マルチ コアによる並列プログラム。 レスポンスタイムを速く。マル チスレッドによる非同期プログ ラム。 レスポンスタイムを速くして、 待つのが気にならないUIを作る 86
end おわりに 87
最後に高速化を比喩で。 高速化はダイエットに似てい ます。 おわりに 88
太ります! DEBU! 89
測ります!! CHECK!! 90
痩せます!!! YASE!!! 91
リバンウンドします!!!! REBOUND!!!! 92
ごまかします!!!!! BEAUTIFUL!!!!! 93
連載.NETマルチスレッド・プログラミング入門 マルチスレッドとマルチタスクの違い ++C++;// 未確認飛行 C マルチスレッド 意味の違いがわかる? タスクとプロセスとスレッド 避けて通れない「非同期処理」を克服しよう ++C++;// 未確認飛行 C 並列処理ライブラリ C# 5.0&VB 11.0新機能「async/await非同期メソッド」入門 並行と並列について-並行コンピューティング技法-を読んで 参考(一部) 並列プログラミング入門!&おさらい! Taskを使って非同期処理 C#5.0のasync/awaitによる非同期処理の使い方 非同期処理でUIスレッドを操作する方法 とあるコンサルタントのつぶやき マルチスレッド Windows フォームアプリケーションの開発 DOBON.NETより高い精度で時間を計測する VC++まわりの非同期処理 増補改訂版Java言語で学ぶデザインパターン入門マルチスレッド編 @IT, Wikipedia, IT用語辞典, StackOverFlow, 94
発表するとめちゃめちゃ勉強 になりますよ。皆さんもぜひ 次回しゃべってください! おわりに 95
ご清聴ありがとうございまし た おわりに 96
https://github.com/moririring/Sp eedupDemo 今日のソース 97