読者です 読者をやめる 読者になる 読者になる

お茶漬けびより

学んだことを整理する場所です。主に、C++, Unreal Engine 4 (UE4) を扱います。

本読み Optimized C++ 1章

C++ 読書

Optimized C++ 1章

読んだ記録を取るためと、内容を整理するために文章にしていくプロジェクト。
飽きないように気をつける。で、Optimized C++ を購入して、とりあえず1章読み終わりました。
オライリー本は、内容が濃いから1ページ読むのに時間がかかる……(1時間半かかった)

1章は、本全体の概要みたいなもので流し読みで良いのだけど、
自分は最適化を意識したことがなかったので、じっくり読んでました。

この本について

この本は、C++ の最適化について書かれているので、 一部別の言語にも利用できるテクニックがあるかもしれないが、 別の言語に向けて書かれたものではない。
また、特定のプロセッサで利用できる命令などを使った最適化はしない。
これは、今の時代アプリは様々なプラットフォーム(主にプロセッサ)で動作するから。
OS も同様。この本は、C++ で何ができるかについて書かれている。

特定の技法(テクニック)を教えるものではない。
どうやって最適化をしていくかを学んでいく本。
考え方に近いかもしれない。また、コーディングプロセスの最適化も扱う。
最初にとりあえず実装するのではなく、最初から高速な処理を書けるようにする。

この本を読めば、以下の方法でコードの性能を改善することができる

  • より良いコンパイラを使い、最適化をオンにする
  • 最適なアルゴリズムを使う
  • より良いライブラリを使い、ライブラリをよりうまく使う
  • メモリ割り当てを減らす
  • コピーを減らす
  • 計算を取り除く
  • 愛的なデータ構造を使う
  • 並行性を増やす
  • メモリ管理を最適化する

1.1 最適化はソフトウェア開発の一部

速度、スループット、メモリ使用、消費電力の改善は、コーディングと同じほど重要。
低性能なアプリは、バグと同じ。

直感で最適化をすることはできない。
実際に計測し、その結果を見て最適化ができたかどうかを判断する。
直感ではなく実験によって最適化を行う。

1.3 最適化しても大丈夫

「単純」で非効率なコードをなぜ書かないのか尋ねられたら、「遅くて無駄なコードを書く時間と同じ時間で効率的なコードが書けるからだ。どうしてわざわざ非効率なコードを書くことを選択するの?」と答えればよい。

良くないのは、何が問題なのか分かっていないのに最適化をすること。
アセンブラで組み直せば速くなるとは限らないし、C++ より C の方が速いとは決まっていない。

大事なのは、何が原因になっているかを見つけること。その原因だけ対処すれば性能は向上する。

アルゴリズムを選択するときは、実験によって示すこと。噂や憶測でそのアルゴリズムを候補から消してしまってはいけない。
プロセッサの性能が高くなるから最適化をしなくていいというのは、嘘。最近のプロセッサの速度は、あまり向上していないし、場合によっては落ちている(個別コアで見た場合)。
特にモバイルプラットフォームだと速度だけでなく、発熱、バッテリーの消費量なども意識する必要がある。そもそもユーザが常に最新のプラットフォームを使うとは限らない。

1.4こちらにナノ秒、あちらにナノ秒

ハードウェアが高性能でも、その上で動く、ソフトウェアが使える資源は極一部。
モバイルやサーバでは、資源に制約がある。

1.5 最適化 C++ コード戦略のまとめ

最適化のホットスポットには、「いつもの容疑者」がいる。
関数呼び出し、メモリ割り当て、ループなど。
もちろんこれだけではないので、この本は、そういった隠れた箇所を見つけやすくする。

1.5.1 より良いコンパイラを使う、コンパイラをよりうまく使う

どのC++ コンパイラを使うべきかについての最も重要なアドバイスは、「C++11 適合コンパイラを使う」ということ

C++11 は、ムーブセマンティクスを実装している(6.6 ムーブセマンティクスの実装)

コンパイラによって最適化の方法は異なる。なので、コンパイラによっては性能が向上することがある。
コンパイラの最適化は、デフォルトでは OFF になっている。これを ON にするだけで解決するときもある。
ただし、デバッグ時は最適化は OFF にする。その方が、処理を追いやすい。

コンパイラの性能は、Intel C++ > Visual C++GNU C++ と言われている。
もちろん必ずこうなるわけではないので、実際に試してみる必要はある。

1.5.2 より良いアルゴリズムを使う

選択を間違ったアルゴリズムを最適化しても性能向上はあまり望めない。
別のアルゴリズムに変えるだけで、性能が向上することがある。
これについては、5章「アルゴリズムを最適化する」で紹介。
5.5「最適化のパターン」では、性能改善に重要な技法について紹介。事前計算、遅延計算、キャッシュなど。
7章「ホットな文を最適化する」で、これらの技法の例を示す。

1.5.3 より良いライブラリを使う

標準 C++ テンプレートとランタイムライブラリは、常に保守され、汎用で非常に頑健でなければいけない。つまり、標準のものが最適とは限らない。8章では、「優れたライブラリを使う」でこの問題を扱う。
C++ 標準ライブラリをマスターすることは、最適化開発者の必須スキル。

  • 選択や整列のアルゴリズム(9章)
  • コンテナクラスを使った最適イディオム(10章)
  • I/O(11章)
  • 平衡性(12章)
  • メモリ管理(13章)

なども扱う。
優れた関数ライブラリAPI は、ユーザに不必要な基本関数を呼ばせない。
ライブラリは、呼び出しコストに見合う最高の効率をユーザのプログラムにもたらすべき。
関数呼び出しのコストについては、7.2.1 で扱う。

1.5.4 メモリ割り当てとコピーを減らす。

文字列の最適化は、4章で扱う。
6章では、動的メモリ割り当てのコストを減らすことを論じる。
コピーを減らすことは、コードの速度向上に明らかに役立つ。
コピーに関するホットスポットは、コンストラクタ、代入演算子、入出力がある。

1.5.5 計算を取り除く

7章と3章を参照

1.5.6 より良いデータ構造を使う

10章、9章を参照。

1.5.7 並行性を高める

12章を参照。

1.5.8 メモリ管理を最適化する

13章を参照。

おわり

後半手抜きだけど、1章はこんな感じ。以上。
1年かけて読み進めていく予定。