404 Not Found

404 Not Found


nginx

パフォーマンスの最適化

[第]48[課では、]C++17/20[の新機能]について学びました。

[今]、[私たちは]パフォーマンス最適化――[C++プログラムを][より高速に][動作させる]――について学びます。

C++の[強みは]パフォーマンスですが、[それをうまく活用するのは簡単ではありません]。


1. パフォーマンス最適化[概要]

(1) 1.1 [なぜ]最適化が必要なのか?

[原則]:

  1. [不要]最適化(時期尚早な最適化)
  2. [まず測定]、[その後]最適化
  3. 最適化アルゴリズム、[再]最適化コード

(2) 1.2 パフォーマンス[ボトルネック]

[ボトルネック] [割合]
アルゴリズム 70%
メモリ[アクセス] 20%
[その他] 10%

[結論]: 最適化アルゴリズムは、最適化コードよりも[重要]である。



2. メモリ[アラインメント]

(1) 2.1 メモリ[アラインメント]とは何か?

メモリ[アラインメント]とは、[データが]メモリ[内の開始]アドレスが、ある値([通常は]2の冪)の倍数であることを指します。

[なぜ重要なのか]?


(2) 2.2 例:memory[アラインメントの影響] (難易度 ⭐⭐)

▶ サンプル 1: オブジェクト指向[プログラミングデモ] (難易度 ⭐)

CPP
#include iostream

struct BadAlignment {
 char c; // 1lessons of
 int i; // 4lessons of(4)
};

struct GoodAlignment {
 int i; // 4lessons of
 char c; // 1lessons of
};

int main() {
 std::cout << "Bad: " << sizeof(BadAlignment) << " bytes" << std::endl;
 std::cout << "Good: " << sizeof(GoodAlignment) << " bytes" << std::endl;
 
 return 0;
}
▶ 試してみよう

[実行結果]([可能性]):

TEXT
Bad: 8 bytes
Good: 8 bytes

💡 ヒント:



3. [キャッシュ対応]

(1) 3.1 CPU[キャッシュ]

CPUの[キャッシュ比]は、メモリの**[100]です。

最適化[原則]:

  1. local[性原理]:[隣接する]メモリへのアクセス
  2. [順次アクセス]:[ランダムアクセスよりも高速]
  3. [キャッシュの無効化を避ける]:[連続していない]メモリへのアクセスを控える

(2) 3.2 例:[行主序] 対 [列主序] (難易度 ⭐⭐⭐)

CPP
#include iostream
### (3) ▶ 2:STL(⭐)

#include vector
#include chrono

int main() {
 const int N = 1000;
 std::vector<std::vectorint> matrix(N, std::vectorint(N));
 
 // ()
 auto start = std::chrono::high_resolution_clock::now();
 for (int i = 0; i < N; i++) {
 for (int j = 0; j < N; j++) {
 matrix[i][j] = 1;
 }
 }
 auto end = std::chrono::high_resolution_clock::now();
 auto row_time = std::chrono::durationdouble(end - start).count();
 
 // ()
 start = std::chrono::high_resolution_clock::now();
 for (int j = 0; j < N; j++) {
 for (int i = 0; i < N; i++) {
 matrix[i][j] = 1;
 }
 }
 end = std::chrono::high_resolution_clock::now();
 auto col_time = std::chrono::durationdouble(end - start).count();
 
 std::cout << ":" << row_time << "..." << std::endl;
 std::cout << ":" << col_time << "..." << std::endl;
 
 return 0;
}


4. コンパイル[器]の最適化

(1) 4.1 最適化[レベル]

[レベル] [マーク] [説明]
O0 [なし] [非]最適化(デバッグ[用])
O1 -O1 [基本]最適化
O2 -O2 [おすすめ]([バランス])
O3 -O3 [徹底的な]最適化
Os -Os 最適化[大小]

(2) 4.2 例:コンパイル[器]の最適化[効果] (難易度 ⭐)

CPP
#include iostream

int main() {
 int sum = 0;
 for (int i = 0; i < 1000000; i++) {
 sum += i;
 }
 std::cout << sum << std::endl;
 
 return 0;
}

コンパイル:

BASH
g++ -O0 main.cpp # 
g++ -O2 main.cpp # ()


5. パフォーマンス[分析ツール]

(1) 5.1 [よく使うツール]

[ツール] [プラットフォーム] [説明]
gprof Linux GCCのパフォーマンス[分析]
perf Linux Linuxperformance[分析ツール]
Valgrind [クロスプラットフォーム] メモリ[分析]
Visual Studio Profiler Windows VS[標準搭載]

(2) 5.2 例:[用]chrono[時間を測定する] (難易度 ⭐)

CPP
#include iostream
#include chrono

int main() {
 auto start = std::chrono::high_resolution_clock::now();
 
 // ...
 long sum = 0;
 for (int i = 0; i < 100000000; i++) {
 sum += i;
 }
 
 auto end = std::chrono::high_resolution_clock::now();
 auto duration = std::chrono::durationdouble(end - start).count();
 
 std::cout << ":" << duration << "..." << std::endl;
 
 return 0;
}



(2) 6.2 アルゴリズム[レベル]

[コツ] [説明]
[適切なデータ構造の選択] ベクトル vs リスト vs マップ
[適切な]アルゴリズム sort 対 partial_sort
[不要なコピーを避ける] [参照]、[移動]

❓ よくある質問

Q 最適化は[必ず効果があるのでしょうか]?
A [必ずしもそうとは限りません]。[まず測定を行い]、[ボトルネックを特定してから]最適化を行うべきです。

Q C++は[一定程度]Pythonより[速い]ですか?
A [必ずしもそうとは限りません]。[もし]アルゴリズムが[同じ]なら、C++は[通常、速い]です。[しかし、不適切な]アルゴリズムを使った場合、C++は[遅くなる可能性もあります]。

Q [ボトルネックがどこにあるかをどう判断すればよいですか]?
A [パフォーマンス]分析ツール(プロファイラ)を[使用]します。

📖 まとめ

[知識ポイント] [要点]
メモリ[アラインメント] [パディングの削減]
[キャッシュに優しい] [順次アクセス]、local[性]
コンパイラの最適化 -O2 [おすすめ]
パフォーマンス[分析] [事前測定],[その後]最適化
最適化[テクニック] 移動セマンティクス、emplace_back

📝 練習問題

  1. 初心者(難易度 ⭐):vector と list をそれぞれ使って 100000 個の整数を格納し、末尾への挿入とランダムアクセスの所要時間の差を比較する。

  2. **中級(難易度 ⭐⭐):[値渡し]と[参照渡し]の[パフォーマンスの][違い]を検証する。[大きな]構造体([vectorint(10000)を含む])を処理する[関数]を書き、[それぞれ]値渡し[と] const 参照渡し[を用いて]実行時間を測定する。

  3. **上級(難易度 ⭐⭐⭐):[使用] std::chrono [高精度計時]、[比較] forループ、STLのfor_each、[範囲] における [3種類の反復処理方法の] パフォーマンス[の差異]。[分析結果]。



[次のレッスン]:ユニットテスト(#50)

Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%