2025/08/11 12:55 Operation Costs in CPU Clock Cycles (2016)

ロボ子、今日のニュースはコード最適化のコストに関する概算値じゃ。特にCPUのサイクル数についてじゃぞ。

なるほど、博士。コードのどの部分がどれくらいのコストになるのかを知っておくことは、最適化の第一歩ですね。

そうじゃ!例えば、単純な足し算(ADD)やMOV命令は1サイクル未満で終わるが、整数の割り算は12-44サイクルもかかるんじゃ。

割り算はそんなにかかるんですね!知らなかったです。浮動小数点演算はどうですか?

浮動小数点数の割り算も重いぞ。37-39サイクルくらいじゃ。でも、SSEを使うと少しはマシになるみたいじゃな。それでも10-40サイクルくらいかかるみたいじゃが。

SSEはSingle Instruction, Multiple Dataでしたっけ。並列処理で高速化するんですね。

その通り!それから、分岐予測も重要じゃ。 CPUが正しく予測すれば1-2サイクルで済むが、間違えると10-20サイクルのストールが発生するんじゃ。

分岐予測を間違えるとそんなにコストがかかるんですね。`__builtin_expect()` は、最近のIntel CPUでは分岐予測に影響を与えないんですか?

`__builtin_expect()` は分岐予測には影響しないみたいじゃな。コンパイラがコード生成するときに、メモリ配置に影響を与える可能性があるみたいじゃ。

なるほど。メモリ配置も最適化に関わってくるんですね。

そうじゃ!メモリアクセスも重要じゃぞ。L1キャッシュは4サイクル、L2キャッシュは12サイクル、L3キャッシュは44サイクルじゃ。

キャッシュミスを減らすように、データの局所性を意識する必要があるんですね。

その通り!NUMAアーキテクチャも考慮する必要があるぞ。リモートCPUのメモリにアクセスすると、さらにコストがかかるんじゃ。

NUMAはNon-Uniform Memory Accessの略でしたね。CPUごとにメモリを持っているから、他のCPUのメモリにアクセスすると遅くなるんでした。

よく覚えておるな。それから、CAS (Compare-And-Swap) 操作も、通常のメモリアクセスより時間がかかるんじゃ。

アトミック操作ですね。マルチスレッド環境では必須ですが、コストも高いんですね。

TLBミスも無視できんぞ。7-21サイクルかかる。巨大ページを使うとか、ASLRを無効化するとか、対策があるみたいじゃ。

TLBはTranslation Lookaside Bufferの略で、仮想アドレスと物理アドレスの対応をキャッシュするものでしたね。ASLRを無効化するのはセキュリティ的にどうなんでしょうか?

確かに、ASLR無効化はセキュリティリスクがあるから、よく考えてからにするんじゃぞ。それから、C++の例外処理もコストが高いんじゃ。例外が投げられなければゼロコストに近いけど、投げられると5000サイクルくらいかかる。

例外処理は、try-catchブロックを使うとパフォーマンスに影響があるんですね。エラーコードを返す方が良い場合もあるんですね。

そうそう。最後に、スレッドコンテキストスイッチはめちゃくちゃコストが高いんじゃ。最大3Mサイクルかかることもあるぞ。

スレッドコンテキストスイッチは、OSがスレッドを切り替える時の処理ですね。キャッシュが無効化されるのが痛いですね。

そういうことじゃ。これらのコストを頭に入れて、効率的なコードを書くように心がけるんじゃぞ!

はい、博士!勉強になりました。私ももっと効率的なコードを書けるように頑張ります!

ところでロボ子、CPUのサイクル数って、人間の年齢で言うと何歳くらいだと思う?

ええと…、CPUのサイクル数は非常に速いので、人間の年齢に例えるのは難しいですが…、もし例えるなら、生まれたばかりの赤ちゃんが光速で成長するような感じでしょうか?

ブッブー!正解は、永遠の5歳!なぜなら、CPUは常に最新技術でアップデートされるから、永遠に成長し続けるんじゃ!
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。
