[過去ログ] Visual Studio 2008 Part 22 (314レス)
前次1-
抽出解除 レス栞

このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
235
(4): 2018/09/16(日)16:37 ID:zL1WUjLu(13/27) AAS
>>231
逆アセンブラ

for (int i=0;i<num;i++) norm += (double)r[i] * (double)r[i];
00000033 33 D2 xor edx,edx
00000035 89 55 E8 mov dword ptr [ebp-18h],edx
00000038 90 nop
00000039 EB 03 jmp 0000003E
0000003b FF 45 E8 inc dword ptr [ebp-18h]
0000003e 8B 45 E8 mov eax,dword ptr [ebp-18h]
00000041 3B 45 FC cmp eax,dword ptr [ebp-4]
00000044 7D 1B jge 00000061
00000046 8B 45 F8 mov eax,dword ptr [ebp-8]
00000049 8B 55 E8 mov edx,dword ptr [ebp-18h]
0000004c DD 04 D0 fld qword ptr [eax+edx*8]
0000004f 8B 45 F8 mov eax,dword ptr [ebp-8]
00000052 8B 55 E8 mov edx,dword ptr [ebp-18h]
00000055 DC 0C D0 fmul qword ptr [eax+edx*8]
00000058 DC 45 F0 fadd qword ptr [ebp-10h]
0000005b DD 5D F0 fstp qword ptr [ebp-10h]
0000005e 90 nop
0000005f EB DA jmp 0000003B
norm = sqrt(norm);
00000061 DD 45 F0 fld qword ptr [ebp-10h]
00000064 83 EC 08 sub esp,8
00000067 DD 1C 24 fstp qword ptr [esp]
0000006a E8 0D 50 7B FF call FF7B507C
0000006f DD 5D D8 fstp qword ptr [ebp-28h]
00000072 DD 45 D8 fld qword ptr [ebp-28h]
00000075 DD 5D F0 fstp qword ptr [ebp-10h]
241: 2018/09/16(日)16:54 ID:LrdaMWHl(3/5) AAS
>>237
ああ。また訂正。

sqrt()が使われていないのは、>>200 >>201 >>202 >>203 の場合で、
それは、ループ内にfprintf()を入れた場合と入れない場合とで、
x87 fpuレジスタのst(0)〜st(7)を使う「期間」が変わるために 80BITから
64BITへの書き戻し丸めの問題のために精度が変わっているだけだった。

一方、あなたが指摘した >>191 では、ちゃんと sqrt() 関数が使われていて、
それだと、IDEからの起動とコマンド・プロンプトからの起動とで、精度が変
わってくると。そして、その場合の逆アセンブル結果は >>235 のように
sqrt() 関数がその場で x87 fpu の fsqrt 命令を使わずに、call 文によって
実際に本当のサブ・ルーチンを呼び出していると。

これはとても興味深い。そのサブ・ルーチンの中が、時と場合によって
精度が変わってくるような書き方をされている可能性が見えてきた。
249: 2018/09/16(日)20:54 ID:zL1WUjLu(21/27) AAS
>>240
さて再見したが、やはりstaticだけで直る理由は分からない。
なお、最適化ミスの場合は、逆アセンブラを読めば分かる。
今のところそれではない。

一応、>>191ソースのtemplate部の逆アセンブルを上げておく。(ただし重複するので頭のみ)
頭はこれ。続きが>>235,236

template<typename T> static double calc_norm_and_regulate(int num, T* r, bool regulate){ // <float> for debug.
double norm = 0;
00000000 55 push ebp
00000001 8B EC mov ebp,esp
00000003 83 EC 28 sub esp,28h
00000006 89 4D FC mov dword ptr [ebp-4],ecx
00000009 89 55 F8 mov dword ptr [ebp-8],edx
0000000c 83 3D 14 2E 76 00 00 cmp dword ptr ds:[00762E14h],0
00000013 74 05 je 0000001A
00000015 E8 FF 52 1B 68 call 681B5319
0000001a 33 D2 xor edx,edx
0000001c 89 55 E8 mov dword ptr [ebp-18h],edx
0000001f 33 D2 xor edx,edx
00000021 89 55 EC mov dword ptr [ebp-14h],edx
00000024 D9 EE fldz
00000026 DD 5D F0 fstp qword ptr [ebp-10h]
00000029 D9 EE fldz
0000002b DD 5D E0 fstp qword ptr [ebp-20h]
0000002e D9 EE fldz
00000030 DD 5D F0 fstp qword ptr [ebp-10h]
254: 2018/09/16(日)22:33 ID:zL1WUjLu(24/27) AAS
>>252
そちらの逆アセンブルは以下の違いが出てるだろ。
static版: fld/fmul/fadd/fstp
非static版: fld/fmul/faddp (fstpが無い)
この非static版の場合、拡張倍精度(80bit)で演算されるから精度が高いことになり、
static版との演算結果に違いが出るのも仕様通りなんだよ。(これは>>200と同じ間違い)

一応、fstpにも80bit版はあって、Intelのマニュアルによると以下。
> オペコード命令説明
> D9 /2 FST m32fp ST(0) をm32fp にコピーする。
> DD /2 FST m64fp ST(0) をm64fp にコピーする。
> DD D0+i FST ST(i) ST(0) をST(i) にコピーする。
> D9 /3 FSTP m32fp ST(0) をm32fp にコピーし、レジスタスタックをポップする。
> DD /3 FSTP m64fp ST(0) をm64fp にコピーし、レジスタスタックをポップする。
> DB /7 FSTP m80fp ST(0) をm80fp にコピーし、レジスタスタックをポップする。
> DD D8+i FSTP ST(i) ST(0) をST(i) にコピーし、レジスタスタックをポップする。
つまり君のstatic版
> 0000001f DD 1D 00 30 CC 00 fstp qword ptr ds:[00CC3000h]
では FSTP /3 m64fp [disp32] であり、そこで64bit(倍精度)に丸められてる。
だからレジスタ(80bit=拡張倍精度)で演算される非static版と結果が異なる。
static版のsftpが DB /7 m80fp なら誤差は出ないはずなんだよ。(Cでどう書くのかは知らん)

だから>>252の場合の誤差なら、仕様通りなんだよ。(片方が倍精度、もう片方は拡張倍精度)
ただし、>>191は逆アセンブル(>>235)を見る限りそれに該当しないし、(両方とも倍精度)
今回の俺の上記逆アセンブル(>>253、中身は君の指摘通りunmanagedにしただけ)も該当しない。(両方とも倍精度)
そして253は何故か直ってしまった。
258
(1): 240 2018/09/16(日)23:35 ID:/oSJzlqn(5/5) AAS
>> 252はRelease版をコンソールで実行したときの逆アセンブル結果。
>それはどうやって得たの?俺はそれが出来ないから困ってる。
calc_norm_and_regulateの次の行に
System::Diagnostics::Debugger::Launch();
を入れてコンソールから実行すると just in time デバッグできるので、デバッガを選んだ後、
Visual Studioの 呼び出し履歴から calc_norm_and_regulate を探して移動する

>> ちなみに、235はDebugモードでコンパイルし、デバッガ配下の逆アセンブル結果でしょ。
>235は、IDE上でReleaseモードでF5で起動し、ブレークポイントを当てて止めて逆アセンブルした結果。

あれ? だとすると最適化していないのでは?
こちらの結果と違うのだが。
前次1-
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル

ぬこの手 ぬこTOP 0.026s