[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends-ml 10107] Re: Java 言語で学 ぶデザインパターン入門第 6 回議事録



村山です.

#基本的且つ高度なネタですよねえ.
#どこまで答が正しいか分からない.

> ええと、ひとつのスレッドがひとつのオブジェクトに対し複数回ロックを
> 取得しようとした場合、1回目のロック取得と、2回目以降のロック取得と
> では挙動が異なりますよね? 2回目以降は待たされないわけですから。
#正確にはモニタというべきだと思う.ちなみに排他制御
#機構としての「ロック」には二回目という概念はありません.

##二回目をやったら,そのままデッドロックになるだけでは....

それと,待つ待たないってのはほとんど関係ないかと.

>  1回目のロック取得動作と、2回目以降のロック取得動作とを
>  比べた場合、2回目以降のロック取得動作の方が軽いのではないか。
> ということなのだと思いますし、単純な実装なら、それは十分あり
> 得ると思うのですが、どうでしょう?
苦しいときのdeveloperworks頼み.
http://www-6.ibm.com/jp/developerworks/java/020125/j_j-threads2.html#5
#IBMはSUNと並んで最先端の最適化技術を持つ企業のひとつ.
#この手の記事の信頼性は高いと思う.

この例では逐次でも30%軽くなるとのこと.
#最適化が難しいのは,この30%ってのが実装や最適化の度合い,
#ハードウエアの構成など,様々な条件によって変わるという点.

ただ,これが「二回目以降の処理に最適化した結果」とは,
やはり考え難いと思います.おそらくは,自スレッドIDの
設定や削除,待ち行列のチェック等にかかる処理が不要に
なる分早いということかと思います.

あるいは,これはデュアルプロセッサーマシンということですが,
そうするとスレッドも無条件でネイティブスレッドになるのでは.

とすればモニタで本当に「ロック」の取得と開放が必要になるので,
その処理がかなり重くなるでしょう.二回目以降はこれを避ける
ために先にモニタを獲得済みか確認するif文が入れてあるとすれば,
一度目よりも二度目の方が軽くなるのも説明がつきますね.
「ロック」に比べれば条件分岐なんて誤差みたいなもん
でしょうから.

これが正しいとすると,シングルCPUのマシン上では,これとは
異なる結果になるでしょう.

ここで紹介されている例では,マルチスレッド下で劇的な速度向上
が達成できていますが,まあ,お世辞にも誉められた設計ではない
ですよね.レガシーシステムを使う場合はこういう手法も捨てた
もんじゃないですが,新しい並列プログラムを開発する場合は,
可能ならばアルゴリズムから見直した方が良いと思います.

> # そもそもベリファイアを抜けたコードなら、「2回目以降のロック
> # 取得動作」って、することないんでは。
少なくとも初回実行時では,多分そこまで過激な最適化は
しないと思います.なんせ呼び出し先のメソッドやクラスが
ロード済みという保証さえない.

> JITレベルで最適化された挙句、
> > > synchronized (b)
> > > {
> > >   b.append(foo);
> > >   b.append(bar);
> > >   b.append(baz);
> > > }
> 結局こういうコードに展開されている、というオチはないんでしょうか。

developerworksの例で言えば,
・Stringの操作などを同期化しても,アルゴリズム上問題はない.
・各スレッドは逐次的に実行されても構わない.
などなどの事実が明らかになってない限り,プログラムの
ロジックが変わってしまいますよね?そうするとバグが
発生する危険性があります.

これは既に「最適化」とは呼べないでしょう.

しかもこれが効果を発揮するのは,
・並列マシンである.
・マルチスレッド環境である.
などに限られますし.