コンテンツにスキップ

最終更新:2026-10-12

C++ False Sharing とキャッシュライン

最近あるコードを見かけました。手動でアラインメントを行っていたので、アラインメントしない場合にはどのような影響があるのか調べてみました。

template <typename T>
class AtomicWithPadding {
 private:
  static constexpr int kCacheLineSize = 64;
  uint8_t padding_before[kCacheLineSize];

 public:
  std::atomic<T> value;

 private:
  uint8_t padding_after[kCacheLineSize];
};

ここで、皆さんが面接で必ず問われるポイントが出てきます:

  • Cache line

そこで、以下のような面接問題がありますが、答えられるでしょうか?

  • cache lineとは何か?
  • MESIプロトコルとは何か?
  • False sharingとは何か?
  • C++ではどのようにFalse sharingを回避・防止するのか?
  • False sharingを回避するとどのようなメリットがあるのか?
  • C++17以降にこの問題を解決するために提供された2つの機能をご存知ですか?

そこで、パフォーマンステストを探してきました。おおよその実装は次のとおりです:

  • a、b、c、dの4つの変数を定義し、複数スレッドで共有する
  • もう1つは、この4つの変数をアラインメントし、n個のスレッドを起動してスケジューリングさせる

以下がbenchmarkの結果です:

------------------------------------------------------------------
Benchmark                        Time             CPU   Iterations
------------------------------------------------------------------
singleThread                  4.05 ms         4.04 ms          133
directSharing/real_time       8.78 ms        0.069 ms           77
falseSharing/real_time        8.81 ms        0.083 ms           74
noSharing/real_time           1.16 ms        0.071 ms          578

noSharingが非常に良い結果を出していることがわかります!キャッシュヒット率が大幅に向上しています。もちろん、ここでperfを使って分析するとさらに良いでしょう。L1 cache missを見ることができます。

以上の解答は知識星球で更新済みです。ぜひ一緒に議論して、コメント欄で交流しましょう。よろしくお願いします〜

関連トピック

コメント