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

このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
240
(8): 2018/09/16(日)16:53 ID:/oSJzlqn(1/5) AAS
たぶん2008の最適化ミスだと思う。
static double norm = 0;// ←"static"を追加する
にするとか、最適化オプションをいじると
Release/コマンドプロンプトからの起動でも
0x1ff68ddfb62221ddになる
244: 2018/09/16(日)17:22 ID:zL1WUjLu(17/27) AAS
>>240
現象確認した。こちらでも再現した。
逆アセンブルは、以下。(肝心のループ部分は次レス内)

正直、fld/fmul/fadd/fstpのループ部分は変わらず、
normのアドレスが [ebp-10h](つまりローカル)から
ds:[00A4AD40h](つまりグローバル)に変わっただけであり、
これで結果が変わるのはかなり奇妙な気もするが、何か見落としがあるのかも。

>>240逆アセンブル(static付加版)
template<typename T> static double calc_norm_and_regulate(int num, T* r, bool regulate){ // <float> for debug.
static double norm = 0;
for (int i=0;i<num;i++) norm += (double)r[i] * (double)r[i];
00000000 55 push ebp
00000001 8B EC mov ebp,esp
00000003 83 EC 20 sub esp,20h
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 38 00 00 cmp dword ptr ds:[00382E14h],0
00000013 74 05 je 0000001A
00000015 E8 FF 52 30 68 call 68305319
0000001a 33 D2 xor edx,edx
0000001c 89 55 F0 mov dword ptr [ebp-10h],edx
0000001f 33 D2 xor edx,edx
00000021 89 55 F4 mov dword ptr [ebp-0Ch],edx
00000024 D9 EE fldz
00000026 DD 5D E8 fstp qword ptr [ebp-18h]
00000029 33 D2 xor edx,edx
0000002b 89 55 F0 mov dword ptr [ebp-10h],edx
0000002e 90 nop
0000002f EB 03 jmp 00000034
245: 2018/09/16(日)17:22 ID:zL1WUjLu(18/27) AAS
>>240逆アセンブル(続き)(static付加版)

00000031 FF 45 F0 inc dword ptr [ebp-10h]
00000034 8B 45 F0 mov eax,dword ptr [ebp-10h]
00000037 3B 45 FC cmp eax,dword ptr [ebp-4]
0000003a 7D 21 jge 0000005D
0000003c 8B 45 F8 mov eax,dword ptr [ebp-8]
0000003f 8B 55 F0 mov edx,dword ptr [ebp-10h]
00000042 DD 04 D0 fld qword ptr [eax+edx*8]
00000045 8B 45 F8 mov eax,dword ptr [ebp-8]
00000048 8B 55 F0 mov edx,dword ptr [ebp-10h]
0000004b DC 0C D0 fmul qword ptr [eax+edx*8]
0000004e DC 05 40 AD A4 00 fadd qword ptr ds:[00A4AD40h]
00000054 DD 1D 40 AD A4 00 fstp qword ptr ds:[00A4AD40h]
0000005a 90 nop
0000005b EB D4 jmp 00000031
norm = sqrt(norm);
0000005d DD 05 40 AD A4 00 fld qword ptr ds:[00A4AD40h]
00000063 83 EC 08 sub esp,8
00000066 DD 1C 24 fstp qword ptr [esp]
00000069 E8 0E 50 88 FF call FF88507C
0000006e DD 5D E0 fstp qword ptr [ebp-20h]
00000071 DD 45 E0 fld qword ptr [ebp-20h]
00000074 DD 1D 40 AD A4 00 fstp qword ptr ds:[00A4AD40h]
246: 2018/09/16(日)17:22 ID:zL1WUjLu(19/27) AAS
>>240逆アセンブル(続き)(static付加版)
if (regulate) for (int i=0;i<num;i++) r[i] = (T)(r[i]/norm);
0000007a 0F B6 45 08 movzx eax,byte ptr [ebp+8]
0000007e 85 C0 test eax,eax
00000080 74 28 je 000000AA
00000082 33 D2 xor edx,edx
00000084 89 55 F4 mov dword ptr [ebp-0Ch],edx
00000087 90 nop
00000088 EB 03 jmp 0000008D
0000008a FF 45 F4 inc dword ptr [ebp-0Ch]
0000008d 8B 45 F4 mov eax,dword ptr [ebp-0Ch]
00000090 3B 45 FC cmp eax,dword ptr [ebp-4]
00000093 7D 15 jge 000000AA
00000095 8B 45 F8 mov eax,dword ptr [ebp-8]
00000098 8B 55 F4 mov edx,dword ptr [ebp-0Ch]
0000009b DD 05 40 AD A4 00 fld qword ptr ds:[00A4AD40h]
000000a1 DC 3C D0 fdivr qword ptr [eax+edx*8]
000000a4 DD 1C D0 fstp qword ptr [eax+edx*8]
000000a7 90 nop
000000a8 EB E0 jmp 0000008A
return norm;
000000aa DD 05 40 AD A4 00 fld qword ptr ds:[00A4AD40h]
000000b0 DD 5D E8 fstp qword ptr [ebp-18h]
}
000000b3 DD 45 E8 fld qword ptr [ebp-18h]
000000b6 8B E5 mov esp,ebp
000000b8 5D pop ebp
000000b9 C2 04 00 ret 4
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]
251
(2): 240 2018/09/16(日)21:43 ID:/oSJzlqn(2/5) AAS
.netの場合、デバッガ配下では(デバッグのため)違うコードを実行しているような気がする。
デバッガの逆アセンブル表示とかasm出力はあまり当てにならないような気もする。
ループ部分だけど、レジスタのみで処理するか、メモリを使用するかで精度が変わるのかも。
そもそも、どっちが正しいのかよくわからんけど...
ループ部分の関数を#pragma unmanagedすると結果が変わるでそれが正しいのかも。
252
(4): 240 2018/09/16(日)21:43 ID:/oSJzlqn(3/5) AAS
static版
0000000e 33 C0 xor eax,eax
00000010 85 F6 test esi,esi
00000012 7E 16 jle 0000002A
00000014 DD 04 C7 fld qword ptr [edi+eax*8]
00000017 DC C8 fmul st(0),st
00000019 DC 05 00 30 CC 00 fadd qword ptr ds:[00CC3000h]
0000001f DD 1D 00 30 CC 00 fstp qword ptr ds:[00CC3000h]
00000025 40 inc eax
00000026 3B C6 cmp eax,esi
00000028 7C EA jl 00000014
0000002a DD 05 00 30 CC 00 fld qword ptr ds:[00CC3000h]

非static版
0000000e D9 EE fldz
00000010 33 C0 xor eax,eax
00000012 85 F6 test esi,esi
00000014 7E 0C jle 00000022
00000016 DD 04 C7 fld qword ptr [edi+eax*8]
00000019 DC C8 fmul st(0),st
0000001b DE C1 faddp st(1),st
0000001d 40 inc eax
0000001e 3B C6 cmp eax,esi
00000020 7C F4 jl 00000016
256
(1): 240 2018/09/16(日)23:13 ID:/oSJzlqn(4/5) AAS
> だから>>252の場合の誤差なら、仕様通りなんだよ。(片方が倍精度、もう片方は拡張倍精度)
そうなの? これが仕様通りならstatic版での違いは仕様通りということになる。
252はRelease版をコンソールで実行したときの逆アセンブル結果。
よって、Release版をコンソールで実行したときのみ(たまたま)レジスタ(80ビット)での演算になるので、
計算結果が変わるのはやむを得ないという結論になるのだが...

ちなみに、235はDebugモードでコンパイルし、デバッガ配下の逆アセンブル結果でしょ。
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.030s