Optimized C++! 最適化の手法集めました Haruka Sao Microsoft MVP for Windows Development Japan MVP Community Connection 2017 Autumn 2017/11/12 Sun
@hr_sao Microsoft MVP for Windows Development [2010-2017] ebisu_optimized.cpp 2017/3/31-11/9
今年2017年2月最適化だけを考えた書籍が日本語で出版! ディスカッション会を隔週で開催 で、実際、この内容どうよ?話を参加者と共有 書籍を元に、さまざまなバックボーンの人たちと話し合う
最適化について考える機会 とにかく実行速度を早くしてくれと言われた なんとなく処理に時間がかかってる気がする そもそも最適化するのが好き(?)
Agenda プログラムを書き始める前に知るべきこと 最適化をする直前に考えること 最適化を実施する時のこと 最適化技法例
プログラムを書き始める前に知るべきこと
速いプログラムは正しいってこと 色んな意見がありますが 「結果的に高速に動くプログラムが良い」 に決まってる →低性能はバグと同じ ただし… →低性能はバグと同じ ただし… いつでもどこでも最適化して良いんです!
してはいけない事や間違った思い込み1 アセンブラやC言語で書き直す C++の方が速い 手書きには限界がある
してはいけない事や間違った思い込み2 良くないアルゴリズムを最適化する 最初から良いアルゴリズム/ライブラリを採用しよう もう既に先駆者がいてます 後から最適化する →例えば構造化の最適化などは後から無理
してはいけない事や間違った思い込み3 ホットじゃない箇所を必死に最適化する 雰囲気でボトルネックを探す 実験、計測が全て 直感だけで最適化に時間をかけないこと
最適化をする直前に 考えること
最適化しないといけないなと思った時… 計測することだけが 最適化の効果があり!を証明できる 計測する、コストを見積もる どこが、どこまで速くなればいいのか決める 最適化の前後で計測する 30%くらいは速くなるもんらしいです
最適化を実施する時のこと
C++で最適化出来る箇所 文字列 アルゴリズム 動的変数割り当て ホットな文 ライブラリ 探索と整列 データ構造 I/O 並行性 メモリ管理 計測後に、取り組む順番も大事… 効果的だと一般的に思われている順番
std::vector,deque,list,map 文字列 アルゴリズム 動的変数割り当て ホットな文 ライブラリ そもそもコピーが多い 探索と整列 データ構造 I/O 並行性 メモリ管理 アルゴリズムとデータ構造 桁違いに速くなる std::vector,deque,list,map お金があるから使うのと同じ 標準だけでは無理 loop, function 標準だけでは無理 何でも出来る人は要らない マジで自作する気? 3. ライブラリ作者なら、Move semanticsを使ったり、不要なクラスコピーの禁止、関数呼び出しを減らす 4. 地味にdo-while()で判定を一回減らす、++i , 乗算をシフトと加算に書き換える、などあるけど、低レベルな技法をするくらいならコンパイラの方が賢いのであまり役に立たない そもそも呼び出し回数を減らす、使ってないvirtualを取り除くなど 6. ハッシュテーブルサイコーじゃないし 8. 外界との唯一のつながりがfile, OS固有のものに頼るしかない 9. 標準にはプロセスの概念はない(11でようやくスレッド入った)標準では無理, std::threadよりasyncとかあるけど、優先順位もつけられないスレッドとか…( ;∀;)、ロックフリープログラムもコストに見合う速度が得られるかどうか… 10.Newとかアロケータに手を入れる前にすべきことがある
最適化技法例
ホットスポットの調べ方 みんなどうやって調べてるの? プロファイラ ブロック単位で速度計測 VSでF10で実行していって遅い箇所 適当にBreakして最初に止まった箇所 ホットな文は10%程度といわれる
ここがホントにボトルネックって、設計を疑った方が… If - else if –elseの書き順 最初に if(true)になるなら、if-else ifで書く (switch caseよりも) →CPUのコンパイル分岐予測で if(true) を予測する(ものもある)ため ここがホントにボトルネックって、設計を疑った方が…
ROV確認は…コンストラクタにログ仕込むか… 右辺値参照の関数戻り値はやめよう RVOの最適化にまかせた方が良い 変にreturnでstd::move書いて、move失敗したら、copyが走るor落ちるのでマジデ良くない std::vector<int> && test(){ std::vector<int> vec; return std::move(vec); } ちょっとだけC++っぽい話も return-value-optimization コンパイラの最適化とかに任せたほうが良い ROV確認は…コンストラクタにログ仕込むか…
C++AMPは…ごめん(ここんとこcuda大人気) 並行処理は標準だけで頑張るな 記述コストが高すぎる…(C++17 parallelに期待?) Boost.Thread TBB (計算だけならおススメ) openBLAS, Eigen (高機能な数値計算) TBB:インテル Cuda:NVIDIA C++AMPは…ごめん(ここんとこcuda大人気)
Summary
Summary 最適化プロセス 正しいプログラムを書く 測定する 目標を決める 最適化する 測定結果を調べる
https://ebisu-effective-modern-cpp.connpass.com/ 次回勉強会 2017/11/29(水)~開始! 数回予定(#^.^#) C++14の復習 C++17の予習(言語系, ライブラリ系) https://ebisu-effective-modern-cpp.connpass.com/