[過去ログ] マルチスレッドプログラミング相談室 (986レス)
前次1-
抽出解除 レス栞

このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
444
(7): 02/08/31 21:37 AAS
AA省
445: 442 02/08/31 23:09 AAS
>>443,444
どうもありがとうございます。
基本的な考えは間違っていないようで、安心しました。

> 書いてあるプログラムも、「いったん判断式を評価したら、二度と評価しない」
> となっているので、その点もよい。

この理由がよくわかりませんでした。

私が if(G == 0) を付けたのは、
「判断式を評価する時間がもったいないから」というだけで
深い意味はなかったのですが、
他にも意味があるのでしょうか?
(判断式を何度評価しても動作に支障がない場合)

また、444 さんのコードの意味もよくわかりません。
void init_G()
{
 lock();
 if(G == 0) {
  if (...) G = 1;
  else G = 2;
 }
 unlock();
}
だけではまずいでしょうか?
lock() にかかる時間的コストを考慮?
lock() と unlock() が対になっていない点も疑問です。
446: 444 02/09/01 00:34 AAS
ごめん。unlockの位置は{}とインデントをつけた時にミスった。

G==0を2度やっているのは、コストの問題。
本当にlockする必要があるのは最初だけで、それ以降は常にG!=0なのだから、
そのためだけに毎回lockするのは時間的に無駄だから。

例えば、Singletonなんかでインスタンスを初期化/取得する場合でも、
毎回実行する部分は出来るだけ軽くすべきであり、
最初以外はlockせずに値を取得出来るようにするため。
447: 444 02/09/01 00:36 AAS
よく見たら、
>lock() にかかる時間的コストを考慮?
って書いてあった。その通りです。
448
(1): 02/09/01 01:12 AAS
>>444
そのコードだとGをvolatile宣言する必要はナシ。
そもそも、volatile宣言された変数へのアクセスって
意外とコスト高なんで注意すべし。

ちなみに>>444のアルゴリズムはDouble-Checked Lockingと
呼ばれているんだが、場合によってはうまく動かないことが
知られている。

具体的には、初期化の対象がatomicなアクセスが保証されている
primitive型の変数ではなく、緩いメモリモデルを採用している
プラットホーム上で動かした場合に、うまく動かない可能性がある。
緩いメモリモデルの例としてはJava memory modelとかがあるから
参考として以下の記事なんかを読んでおくのもいいよ。
外部リンク[html]:www.cs.umd.edu
449: 444 02/09/01 01:36 AAS
どうもありがとう。
C/C++でも、volatileは必要無いのかな?
つまり、lockした後の再判定時に、コンパイラの最適化で
レジスタ等にキャッシュされた値を読んでしまうのを防ぐ必要があるかなと。

コスト的にも、C/C++なら、スタック以外の変数(の読み出し)にかかるコストは、
volatileでもそう変わらないと思ったし(読み出しが一回だけの場合)。
Javaなら、インスタンス変数をキャッシュする関係で差がつくのはわかるけど、
>>444は元々C/C++を想定していたから。
ただ、スタック上の変数の場合は、C/C++でもレジスタ割り付けの関係で差が付きそう。

あと、問題があることは知らなかった。
操作対象がatomicに操作できなくても、判定するためのフラグを用意すれば
一般的に解決できる問題なのかな?
とりあえず、リンク先読んでみる。
450: 444 02/09/01 02:19 AAS
とりあえず、マルチプロセッサ環境において、
・コンストラクタが実行されて初期化されるまでの間
・(C/C++などのCPUキャッシュの同期が保証されていないものでの)メモリからの読み出し時
に問題があることはわかった。
その他はまだよく理解出来てないけど。
451
(1): 442 02/09/01 03:01 AAS
>>444
どうもありがとうございます。
おかげ様で大変よくわかりました。感謝感謝です。

今度は
>>448
volatile宣言の必要がないというのがわかりません。

(444さんと同じ考えですが) volatileが無いと、
lock とunlock が通常の関数呼び出しとして実装されている
なら大丈夫としても、
仮にこれらがインライン展開される関数やマクロだった場合に、
・lockの直後のif文で G がメモリから再ロードされるかどうか
・更新後の Gの値がunlockの前でメモリに書き込まれるかどうか
が保証されないのでは? と思えます。
前次1-
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル

ぬこの手 ぬこTOP 0.052s