[過去ログ] 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;
省19
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]
省13
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]
省18
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
省16
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
省13
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.035s