- PR -

アウトオブオーダーについて

投稿者投稿内容
よねKEN
ぬし
会議室デビュー日: 2003/08/23
投稿数: 472
投稿日時: 2007-03-07 12:34
引用:

Jittaさんの書き込み (2007-03-07 12:12) より:
足し算は、計算の順序を変えても、結果は変わりませんから。



今回の話題のように浮動小数点数の足し算なら
計算順序により結果が変わる場合がありますね。
(情報落ち誤差)

なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2007-03-07 12:35
引用:

Jittaさんの書き込み (2007-03-07 12:12) より:
あまり関係ないけど、気になったことをひとつ。
足し算は、計算の順序を変えても、結果は変わりませんから。
(a+b)*c と a+(b*c) なら変わるけど


計算順序による誤差ならあるのでは?
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2007-03-07 13:33
単一CPUの場合のコンパイラによるOoOだろうと、
Hyper Threading,SMP,Multi CoreによるOoOだろうと、
その言語なり実行環境が保証する方法できっちりと
同期なりメモリバリアなりすれば問題は回避できます。

それで問題が起こるなら、コンパイラや実行環境のバグです。
正しい方法で回避してしないのならば、ライブラリのバグです。

#その数値ライブラリがマルチスレッドやHT以上の
#環境での動作をサポートしないというのならば
#仕様として仕方がないかもしれませんけど。
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2007-03-07 14:04
引用:

あしゅさんの書き込み (2007-03-07 13:33) より:
単一CPUの場合のコンパイラによるOoOだろうと、
Hyper Threading,SMP,Multi CoreによるOoOだろうと、
その言語なり実行環境が保証する方法できっちりと
同期なりメモリバリアなりすれば問題は回避できます。


多分マルチスレッドとか関係ない話じゃないですかね?
※アウトオブオーダって出てくるのが言葉的に怪しいですが。

単に計算順序が異なれば結果が同一にならないのは、
バグではなく仕様です、といわれてるだけのような気がします。
※マルチスレッドとか、要は実行時に変わってしまうような話ではなくて、
 元々異なる順序の計算をしてるプログラム部分があるので同じにならないだけ、
 みたいな。

--追記
あるいは単にこの計算ライブラリの仕様として、計算順序が場合によって変わることが
ありえるので、同一結果を返すことは元々保証してないです、というだけの話とか。
※そういうのをアウトオブオーダっていうのか、ってのは置いといて。

少なくとも、CPUなどでのいわゆるアウトオブオーダ実行とかとは
関係ないんじゃないかと思われます、なんとなく。


[ メッセージ編集済み 編集者: なちゃ 編集日時 2007-03-07 14:18 ]
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2007-03-07 14:06
引用:

やすさんの書き込み (2007-03-06 12:09) より:
ここで質問なのですが、例えば、
a+b+c
という計算式をプログラムで書いた場合、
(a+b)+c
の順番で計算されることもあれば
a+(b+c)
の順番で計算されることもあるのでしょうか?


ありません。

引用:

私は、同じプログラム(計算式)、同じ入力データ、同じマシン
であれば何回実行しても、同じ順番で実行され、必ずピッタリと
同じ答えが返るものだと思っていました。

この考えは間違っているのでしょうか?


アウトオーダーに限って言えば正しいです。アウトオブオーダーにより命令の並べ替えを行いますが、それは実行結果に影響を与えない範囲に限られているはずです。演算順序が入れ替わってしまうような事は無いはずです。もし結果に影響を与えるような命令の並べ替えが行われているなら、それはCPUのバグですね。

メモリバリアの話はハードウェアへのアクセスなどで問題になります。その演算ライブラリがDSP等を使うものなら問題になるでしょうけど、演算ライブラリだけなら関係ないでしょう。仮に関係があったとしても、適切な排他処理を行っていないのはライブラリのバグですね。

Intelのコンパイラなどは処理の一部を複数のスレッドに分割して最適化をはかりますが、やはり演算結果が変わるような最適化を行うはずはありません。もし影響を与えるような最適化が行われているなら、それはコンパイラのバグですね。

そのメーカーが全てを承知の上でアウトオブオーダーを原因にしているなら、ずいぶん不誠実な会社だと思います。逆に知らずにアウトオブオーダーを原因にしているなら、技術力を疑わざるおえません。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2007-03-07 23:12
「アウトオブオーダー」という言葉は、あまり使ったことがないので、もしかしたらつぎの例は「アウトオブオーダー」とは違うのかもしれませんが、入力に"同じ"値を使っていても結果が異なる例です。

コード:

import java.util.*;

public class Hoge {

public static void main(String[] args) {
Double a = new Double(10000000000000.9);
Double b = new Double(-10000000000000.8);
Double c = new Double(0.007);
Map map = new HashMap();
if (new Random().nextDouble() < 0.5) {
System.out.println("true");
map.put("suzi", a); // この場合、結果は t = 0.107421875
} else {
System.out.println("false");
map.put("sui", a); // この場合、結果は t = 0.106609375
}
map.put("tdka", b);
map.put("c", c);
double t = 0.0;
for (Iterator it = map.values().iterator(); it.hasNext(); ) {
Double d = (Double) it.next();
t += d.doubleValue();
}
System.out.println("t = " + t);
}
}


すなわち、HashMap の value は同じだけど、key が違う場合に結果が異なります。結果を求めるのに value しか使いませんが、key が違うと value の順序が変わるわけです。前回、マルチスレッドとして挙げた例とは、多少背景は違いますが本質は同じでしょう。

なにをもって「同じ」入力と考えるかにもよりますが、画面でリストボックスに入力したような値だと、行の追加・削除などが内部の状態にも影響して見た目は同じでも内部状態は異なり、イテレートの順序も異なるということはありそうです。

ファイルだけを入力して、結果が異なるというのならば、マルチスレッド位しか思い浮かびませんが。
あるいは、なにかをシミュレートするのに擬似乱数を使っていて、シードが時刻に依存するようになっているとか。これはイヤですね。シードは固定か選べるようにしてほしいものです。

#顔文字が化けたので、あとで修正しました。

#以下、あとで追加。
#ここは「Insider.NET 会議室」でしたね。ソースコードは Java→C# に翻訳して読んでください(汗)。

--
unibon {B73D0144-CD2A-11DA-8E06-0050DA15BC86}

[ メッセージ編集済み 編集者: unibon 編集日時 2007-03-07 23:13 ]

[ メッセージ編集済み 編集者: unibon 編集日時 2007-03-08 09:23 ]

[ メッセージ編集済み 編集者: unibon 編集日時 2007-03-08 09:24 ]
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2007-03-08 00:00
引用:

unibonさんの書き込み (2007-03-07 23:12) より:
「アウトオブオーダー」という言葉は、あまり使ったことがないので、もしかしたらつぎの例は「アウトオブオーダー」とは違うのかもしれませんが、入力に"同じ"値を使っていても結果が異なる例です。



この例はOoOの問題とは関係ないんじゃないでしょうか。
少なくとも同一スレッド上ではソース上の順序から規定される
評価順序の通りに実行されているように動作するのでは?

同一スレッド上では評価順序の通りに見えるが、
内部の詳細では命令がリオーダーされる場合があるため、
他のスレッドから見ると辻褄が合わなくなってしまう現象かと。
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2007-03-08 02:40
引用:

unibonさんの書き込み (2007-03-07 23:12) より:
すなわち、HashMap の value は同じだけど、key が違う場合に結果が異なります。結果を求めるのに value しか使いませんが、key が違うと value の順序が変わるわけです。前回、マルチスレッドとして挙げた例とは、多少背景は違いますが本質は同じでしょう。


いや、これはa+b+cの計算順序が変わってるんじゃないでしょ?ってだけの話です。
言ってみれば、aとbとcの値自体が変わっているだけです。

ただ、件のライブラリの内部動作的に、こういう風に順序が変わる可能性があるつくりになっている可能性があるのかな?とは思いますが。

いわゆるアウトオブオーダとか、マルチスレッドによる特殊な影響とかとは全然関係ない話です。


[ メッセージ編集済み 編集者: なちゃ 編集日時 2007-03-08 02:42 ]

スキルアップ/キャリアアップ(JOB@IT)