C++ のメモリ一貫性モデルってなんか直感とあわない

最近C++11のコードを少し真面目に見てるのでメモリモデルとかもちょっと見たのだけど、なんか納得いかない。



C++のメモリモデルは、変数へのアクセス毎に、壁を作るのだけど、コード書いてる時の意識としては、「こっからここのアクセスは並びかえてもいいけど、これ以降は並びかえないでね。」みたいな複数アクセスを塊とする意識をしていて、変数単位で何か考えることはほぼない。


ハードウェアの実装もそうなっていて、今のCPUのメモリバリア系の命令は、僕の理解としては、変数アクセスに壁を作るのではなくて、ストアバッファ、プリフェッチャに壁を作ってるという認識。


まあでもこれは、僕がハードウェアの理解からメモリモデルの理解へと進んだから、そっちのほうに思考ができてしまっているだけで、ちゃんとC++の勉強をしてから理解した人は違うのかもしれない。


でもやっぱC++のは微妙だと思うけど。


ハードウェア実装から独立したかったという意図を感じるけど、あれ、一貫性の空間がグローバルに一個しかないから、まだ今のCPUに依存してしまってる気がするんだよな。

CellのSPEのDMAのように(あれは直接C++の変数アクセスとは対応できないけど)、メモリアクセス毎に順序を区別するタグを付けられるCPUが出てくる可能性はゼロでは無いと思うんだよね。その時に、今のC++のでは表現できない。

ちゃんとやるなら、store とかに memory_order に加えて、識別子付けられるようにして、

std::atomic<int> a, b, c, d;

// a->b は保証されるが、 a->c, b->c は保証されない

a.store(0, release, 0);
b.store(0, release, 0);
c.store(0, release, 1);
d.store(0, release, -1); // なんか特殊な値で全部順序付け

みたいにすべきだという気がする。(まあ、メモリモデルいじって最適化しようとするアーキテクチャ自体あんま好きではないが…それはいいとして)


つまり、今のC++のメモリモデルは、

  • 現存するCPUのメモリモデルと比べて無駄に複雑 (今のCPUはバリア命令は3つぐらいしか無いけど、memory_order は6種類ある)
  • な割に、将来のアーキテクチャに対応できるわけでもない

という感じがある。