Re: マルチCPUのキャッシュ(コヒーレンシ)について質問
"goron" <naoij@m.ieice.org> wrote in message
news:cpkim5$mbg$1@dojima-n0.hi-ho.ne.jp...
> goronです。回答ありがとうございます。
>
> 複数キャッシュに対してコヒーレンシを成り立たせるために、andoさんが
> 説明されたような動作を行えばよいというのは判ります。しかし例えば、
>
>> 複数のCPUが全く別の処理を行っていれば,関係ありませんが,複数のCPUで
>> 処理を分担する場合には一つのCPUのStoreした結果を別のCPUがLoadすること
>> は当然起こるわけですが,Storeした結果がメモリに何時反映されるのか分か
>> らないのでは困ります。
>
> 何時反映するのか、の何時というのは時間ではない(つまり1cycle前にダーテ
> ィになったから反映しなければならないとか)のではないかと思います。時間
> だと外部要因などにより予想外の動作をした場合、結果が変わってしまう可能
> 性がある。逆に外部要因で変わるぐらいのアバウトさでいいなら、コヒーレン
> シって本当に必要なのでしょうか。その場合多少昔のデータを持っていてもあ
> んまり変わらない気がする。というか具体的な問題点がよくわかりません。
何方かが書かれていますが,キャッシュコヒーレンシというのはキャッシュ有りのマシンで,キャッシュ無しと同じように見せる機構で,同期の問題を解決する機構ではありません。
何がコヒーレンシかというと,あるアドレスのデータはシステムとしてある瞬間においては同じ値であるということを保証するというのが目的です。同じアドレスでも書き込みが起こればデータは変わるので,違った時点で見ると値は変わりえます。ここである瞬間の定義が問題になりますが,キャッシュシステムとしてコヒーレンシのポイントというのが定義されて,例えばL2キャッシュに書き込んだ瞬間に全CPUに対してそのアドレスのデータが変わったというように動くとかのように設計されます。
>
> 従って実際は時間ではなく、各スレッド間のプログラム位置的相関関係という
> か同期すべきポジションが必ずあるということでしょうか。つまりセマフォ等
> で必ず同期を取る必要性があると思っていいのでしょうか。しかしセマフォな
> ど同期機構と必ずセットなのだとするとパタヘネにしろ他の書籍にしろそんな
> こと書いていないので、やっぱりよくわかりません。それともそういったこと
> とは関係なくコヒーレンシは必要でしょうか。
>
キャッシュコヒーレンシがあるから同期が取れるわけではなく,別物と考えた方が良いと思います。一つのCPUが書き込んだデータを別のCPUが確実に受け取るには,キャッシュコヒーレンシがあっても,第一のCPUが少なくともキャッシュに書き込んだ後にReadしなければなりません。早めに第二のCPUが読めば,それが正しい動作ですが,古い値を読むことになります。
> 次の疑問として、CPU1_Read -> CPU2_Read -> CPU1_Write -> CPU2_Writeはど
> うなのかなというのがやっぱりあります。これを避けるためにはReadして変更
> してWriteする動作全体を単数にする必要があり、そのためにはそれを囲うよう
> な排他処理をする必要がありますでしょうか。つまりセマフォがやっぱり必須
> なのかと。
上記のケースはCPU1とCPU2の実行順序は保証できないので,CPU1_Read→CPU1_Write→CPU2_Read→CPU2_Writeと実行される場合も,CPU1_Read→CPU2_Read→CPU2 _Write→CPU1_Writeと実行されるケースもあり,CPU1内の実
行順序とCPU2内の実行順序は保たれるとしても,それらの相互関係は保証できません。従って,セマフォなどを使うかDekker Algorithmのようなものを使って同期をとる必要があります。
また,最近のプロセサではWeak Memory Orderを採用しているものが多く,プログラムに書かれたメモリアクセスの順番と実際に実行される順番が一致しない(性能が出るように順序を勝手に最適化する)ので,バリアを適切に挿入しないと従来のDekker
Algorithmなどが正しく動かなくなります。
>
> と、上述のように共有メモリを扱うにはどのような処理をするにも必ず同期が
> 必要になるのかな、という気がするのですが。逆に言えば必ず同期がいるのな
> ら、同期解除時にソフトが他のキャッシュをインバリデートする機構を付ける
> とかすれば、機構も簡易になるし、まとめてインバリデートするわけだからバ
> スも込まないし、って思うのですが、自動でなければならない理由がいまいち
> わからなくて。
> やっぱり勘違いがありますかねー。
>
同期を必要とする場合に全てのキャッシュをインバリデートすればコヒーレンシは保たれると思います。しかし,同一CPUからあるアドレスにD1,D2という順序で書いたものを別CPUで2回読んだ時にD1,D1と読むか,D1,D2と読むか,D2,D2と読むかというケースはあるが,D2,D1と読むことはないということに基づいて同期をとるDekker Algorithmなどを使われていると,どこでどのように同期を
取られているかをハードで識別することは不可能です。
また,Test&SetやSwapなどのアトミック命令が使われた場合にキャッシュをインバリデートするというのも必ずしも効率が良いとは思えません。例えばスピンループでセマフォをチェックしているとするとスピンループごとにキャッシュのインバリデートが出たりします。勿論,キャッシュコヒーレンス機構があれば,先ずReadでセマフォが空いているかを見て,空いていればTest&setを出すというやり方がありますが,大部分のCPUがスピンループに入っている場合は,それらのCPUが皆,セマフォが空いたことをほぼ同時に検出してTest&setを出すので,一番厳しいケースではあまり助かりません。
焼酎を飲みながらほろ酔いで書いているので,大筋は良いと思いますが,細部においては多少間違っている部分があるかも知れません。
Ando_san
Fnews-brouse 1.9(20180406) -- by Mizuno, MWE <mwe@ccsf.jp>
GnuPG Key ID = ECC8A735
GnuPG Key fingerprint = 9BE6 B9E9 55A5 A499 CD51 946E 9BDC 7870 ECC8 A735