[過去ログ]
Visual Studio 2008 Part 22 (314レス)
Visual Studio 2008 Part 22 http://mevius.5ch.net/test/read.cgi/tech/1413180800/
上
下
前
次
1-
新
通常表示
512バイト分割
レス栞
このスレッドは過去ログ倉庫に格納されています。
次スレ検索
歴削→次スレ
栞削→次スレ
過去ログメニュー
238: デフォルトの名無しさん [sage] 2018/09/16(日) 16:42:54.99 ID:zL1WUjLu >>233 ああ、なるほど、了解。 http://mevius.5ch.net/test/read.cgi/tech/1413180800/238
239: デフォルトの名無しさん [sage] 2018/09/16(日) 16:49:54.65 ID:zL1WUjLu >>237 いや、俺が提供した>>191のソースなら使われてるぞ。 >>200のソースでは使われてないが。 ただまあ、彼(200)がsqrtを落としたのも分からなくはない。 誤差が生じる=通常は桁落ちだから、この場合は当然積和部分が怪しい。 あらかじめ彼はそうなると分かっていてそれを落とし、予定調和的な結論にたどり着いてしまった。 それが彼の間違いだった、ということ。 俺は出来るだけ元のソースのままで追跡しようとしている。 元のソースの該当ケー
スと離れてしまっては意味がないから。 そして元ソースではsqrtを使っている。 http://mevius.5ch.net/test/read.cgi/tech/1413180800/239
240: デフォルトの名無しさん [sage] 2018/09/16(日) 16:53:58.12 ID:/oSJzlqn たぶん2008の最適化ミスだと思う。 static double norm = 0;// ←"static"を追加する にするとか、最適化オプションをいじると Release/コマンドプロンプトからの起動でも 0x1ff68ddfb62221ddになる http://mevius.5ch.net/test/read.cgi/tech/1413180800/240
241: デフォルトの名無しさん [sage] 2018/09/16(日) 16:54:10.71 ID:LrdaMWHl >>237 ああ。また訂正。 sqrt()が使われていないのは、>>200, >>201, >>202, >>203 の場合で、 それは、ループ内にfprintf()を入れた場合と入れない場合とで、 x87 fpuレジスタのst(0)〜st(7)を使う「期間」が変わるために 80BITから 64BITへの書き戻し丸めの問題のために精度が変わっているだけだった。 一方、あなたが指摘した >>191 では、ちゃんと sqrt() 関数が使われていて、 それだと、IDEからの起動とコマンド・プ
ロンプトからの起動とで、精度が変 わってくると。そして、その場合の逆アセンブル結果は >>235 のように sqrt() 関数がその場で x87 fpu の fsqrt 命令を使わずに、call 文によって 実際に本当のサブ・ルーチンを呼び出していると。 これはとても興味深い。そのサブ・ルーチンの中が、時と場合によって 精度が変わってくるような書き方をされている可能性が見えてきた。 http://mevius.5ch.net/test/read.cgi/tech/1413180800/241
242: デフォルトの名無しさん [sage] 2018/09/16(日) 16:56:42.67 ID:LrdaMWHl >>239 >いや、俺が提供した>>191のソースなら使われてるぞ。 > >>200のソースでは使われてないが。 了解。 問題を切り分けるため、sqrt() を使わなかった場合の Release版での、 IDE起動とコマンドrライン起動の精度の違いを実験してみて欲しい。 http://mevius.5ch.net/test/read.cgi/tech/1413180800/242
243: デフォルトの名無しさん [sage] 2018/09/16(日) 17:02:35.56 ID:LrdaMWHl ちょっとしばらく、ここを離れる。 http://mevius.5ch.net/test/read.cgi/tech/1413180800/243
244: デフォルトの名無しさん [sage] 2018/09/16(日) 17:22:07.21 ID:zL1WUjLu >>240 現象確認した。こちらでも再現した。 逆アセンブルは、以下。(肝心のループ部分は次レス内) 正直、fld/fmul/fadd/fstpのループ部分は変わらず、 normのアドレスが [ebp-10h](つまりローカル)から ds:[00A4AD40h](つまりグローバル)に変わっただけであり、 これで結果が変わるのはかなり奇妙な気もするが、何か見落としがあるのかも。 >>240逆アセンブル(static付加版) template<typename T> static double calc_norm_and_regulate(int n
um, 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 http://mevius.5ch.net/test/read.cgi/tech/1413180800/244
245: デフォルトの名無しさん [sage] 2018/09/16(日) 17:22:29.32 ID:zL1WUjLu >>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 qw
ord 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] http://mevius.5ch.net/test/read.cgi/tech/1413180800/245
246: デフォルトの名無しさん [sage] 2018/09/16(日) 17:22:46.06 ID:zL1WUjLu >>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 fs
tp 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 http://mevius.5ch.net/test/read.cgi/tech/1413180800/246
247: デフォルトの名無しさん [sage] 2018/09/16(日) 17:35:35.70 ID:zL1WUjLu >>242 まだ異なった出力が得られた。 この意味では200がsqrtを外した判断は正しかった。 (彼はそこからさらにループ回数を固定してしまったのが間違いだった) 191ソースを以下に変更した。(sqrtをコメントアウト) ついでに Console::Write(String::Format("{0:E6}, {0:E30}\r\n",norm)); の出力も付けておく。 ソース: template<typename T> static double calc_norm_and_regulate(int num, T* r, bool regulate){ // <float> for debug
. double norm = 0; for (int i=0;i<num;i++) norm += (double)r[i] * (double)r[i]; // norm = sqrt(norm); if (regulate) for (int i=0;i<num;i++) r[i] = (T)(r[i]/norm); return norm; } 結果:(Releaseビルド/コマンドプロンプトからの起動) 0.000000, 0x0007f2c44dfff8f2 1.105348E-308, 1.105348254058510600000000000000E-308 結果:(Releaseビルド/IDEからの起動、Debugビルドは起動方法によらずこちら) 0.000000, 0x0007f2c44dfff8f1 1.105348E-308, 1.105348254058510100000000000000E-308 >>243 了解。いずれにしても
助かってる。 こちらも後30分くらいでちょっと離れる予定。 http://mevius.5ch.net/test/read.cgi/tech/1413180800/247
248: デフォルトの名無しさん [] 2018/09/16(日) 18:30:34.19 ID:HF0YmRsW >>212 ほんそれ http://mevius.5ch.net/test/read.cgi/tech/1413180800/248
249: デフォルトの名無しさん [sage] 2018/09/16(日) 20:54:27.39 ID:zL1WUjLu >>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 0000001
f 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] http://mevius.5ch.net/test/read.cgi/tech/1413180800/249
250: デフォルトの名無しさん [sage] 2018/09/16(日) 21:25:23.90 ID:zL1WUjLu >>219 >>221 /MTと/clrは同時に指定出来ないらしい。(error D8016) /MTdも同じく無理。 もう一つ /MDd ってのがあるから試してみた。 /MDdの結果: Releaseビルドでコマンドプロンプト起動の時のみ ****de、 ReleaseビルドでIDEからの起動だと ***dd。(Debugビルドは起動方法を問わずこっち) (/MDと全く挙動は同じ) これで有効な指摘については全て回答してるかな? 見落としが有れば指摘よろしく。 (規制に引っかかったので遅くなってすまん) 今
のところ、可能性があるのは以下か? ・Releaseビルドをコマンドプロンプトから起動したときのみなぜか精度が高い (>>200から結果的に検出された。今のところ精度が高いときと同じ挙動をしている為) ・ReleaseビルドもIDEから起動すれば結果的にスタックが0初期化されている状態になっており、 俺の本番プログラムに関してはここに当たるバグがある?(>>228) (ただしこれは>>191には該当しない) http://mevius.5ch.net/test/read.cgi/tech/1413180800/250
251: 240 [sage] 2018/09/16(日) 21:43:04.47 ID:/oSJzlqn .netの場合、デバッガ配下では(デバッグのため)違うコードを実行しているような気がする。 デバッガの逆アセンブル表示とかasm出力はあまり当てにならないような気もする。 ループ部分だけど、レジスタのみで処理するか、メモリを使用するかで精度が変わるのかも。 そもそも、どっちが正しいのかよくわからんけど... ループ部分の関数を#pragma unmanagedすると結果が変わるでそれが正しいのかも。 http://mevius.5ch.net/test/read.cgi/tech/1413180800/251
252: 240 [sage] 2018/09/16(日) 21:43:27.78 ID:/oSJzlqn 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 http://mevius.5ch.net/test/read.cgi/tech/1413180800/252
253: デフォルトの名無しさん [sage] 2018/09/16(日) 22:27:34.58 ID:zL1WUjLu >>251 とりあえず落ち着け。一つずつ行こう。 > ループ部分の関数を#pragma unmanagedすると結果が変わるでそれが正しいのかも。 こちらでも確認した。 calc_norm_and_regulateをunmanaged関数にすると、違いはなくなる。 (Releaseビルドの`をコマンドプロンプトで起動した際にも、****ddの結果となる) ただしこちらの逆アセンブル結果は以下だ。(fld/fmul/fadd/fstpであることに注意) for (int i=0;i<num;i++) norm += (double)r[i] * (double)r[i]; 0
007272C C7 45 F4 00 00 00 00 mov dword ptr [i],0 00072733 EB 09 jmp `anonymous namespace'::calc_norm_and_regulate<double>+1Eh (7273Eh) 00072735 8B 45 F4 mov eax,dword ptr [i] 00072738 83 C0 01 add eax,1 0007273B 89 45 F4 mov dword ptr [i],eax 0007273E 8B 4D F4 mov ecx,dword ptr [i] 00072741 3B 4D 08 cmp ecx,dword ptr [num] 00072744 7D 1A jge `anonymous namespace'::calc_norm_and
_regulate<double>+40h (72760h) 00072746 8B 55 F4 mov edx,dword ptr [i] 00072749 8B 45 0C mov eax,dword ptr [r] 0007274C 8B 4D F4 mov ecx,dword ptr [i] 0007274F 8B 75 0C mov esi,dword ptr [r] 00072752 DD 04 D0 fld qword ptr [eax+edx*8] 00072755 DC 0C CE fmul qword ptr [esi+ecx*8] 00072758 DC 45 F8 fadd qword ptr [norm] 0007275B DD 5D F8 fstp qword ptr [norm] 0007275E EB D5
jmp `anonymous namespace'::calc_norm_and_regulate<double>+15h (72735h) http://mevius.5ch.net/test/read.cgi/tech/1413180800/253
254: デフォルトの名無しさん [sage] 2018/09/16(日) 22:33:32.07 ID:zL1WUjLu >>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 m6
4fp [disp32] であり、そこで64bit(倍精度)に丸められてる。 だからレジスタ(80bit=拡張倍精度)で演算される非static版と結果が異なる。 static版のsftpが DB /7 m80fp なら誤差は出ないはずなんだよ。(Cでどう書くのかは知らん) だから>>252の場合の誤差なら、仕様通りなんだよ。(片方が倍精度、もう片方は拡張倍精度) ただし、>>191は逆アセンブル(>>235)を見る限りそれに該当しないし、(両方とも倍精度) 今回の俺の上記逆アセンブル(>>253、中身は君の指摘通りunmanagedにしただけ)も該当しない。(両方とも倍精
度) そして253は何故か直ってしまった。 http://mevius.5ch.net/test/read.cgi/tech/1413180800/254
255: デフォルトの名無しさん [sage] 2018/09/16(日) 22:34:16.44 ID:zL1WUjLu >>252 > .netの場合、デバッガ配下では(デバッグのため)違うコードを実行しているような気がする。 > デバッガの逆アセンブル表示とかasm出力はあまり当てにならないような気もする。 これは俺も相当疑っているのだが、今のところ尻尾を掴めない。 ILspyだっけ?外部の逆アセンブルツール使えばチェック出来るのかな? いずれにしても、>>251の指摘 ・unmanagedにすれば直る のも事実だし、逆アセンブルを見る限り、これを説明出来る理由もないのも事
実。 http://mevius.5ch.net/test/read.cgi/tech/1413180800/255
256: 240 [sage] 2018/09/16(日) 23:13:48.62 ID:/oSJzlqn > だから>>252の場合の誤差なら、仕様通りなんだよ。(片方が倍精度、もう片方は拡張倍精度) そうなの? これが仕様通りならstatic版での違いは仕様通りということになる。 252はRelease版をコンソールで実行したときの逆アセンブル結果。 よって、Release版をコンソールで実行したときのみ(たまたま)レジスタ(80ビット)での演算になるので、 計算結果が変わるのはやむを得ないという結論になるのだが... ちなみに、235はDebugモードでコンパイルし、デバッガ配下の逆アセンブル
結果でしょ。 http://mevius.5ch.net/test/read.cgi/tech/1413180800/256
257: デフォルトの名無しさん [sage] 2018/09/16(日) 23:24:30.83 ID:zL1WUjLu >>256 > 252はRelease版をコンソールで実行したときの逆アセンブル結果。 それはどうやって得たの?俺はそれが出来ないから困ってる。 > ちなみに、235はDebugモードでコンパイルし、デバッガ配下の逆アセンブル結果でしょ。 235は、IDE上でReleaseモードでF5で起動し、ブレークポイントを当てて止めて逆アセンブルした結果。 俺が貼ってる逆アセンブル結果は全てこの方法で、IDEで表示されているもの。 だからIDEの表示がおかしかったら話が全部おかしくな
る。 君がIDEから独立して逆アセンブル出来ているのなら、その方法を知りたい。 こちらでも試す。 なおILSpy、グダグダ言わずに試してみたが、 当たり前だがmanaged code だとILが出る(x86ではない)ので、 俺って根本的に間違ってたかも? 今までx86のアセンブラで議論してたけど、これって .NET アプリには同梱されていないというオチ? (まあその場合は君がやっている外部逆アセンブルが単純には出来ないはずなのだが) http://mevius.5ch.net/test/read.cgi/tech/1413180800/257
258: 240 [sage] 2018/09/16(日) 23:35:36.48 ID:/oSJzlqn >> 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で起動し、ブレークポイントを当てて止めて逆アセンブルした結果。 あれ? だとすると最適化していないのでは? こちらの結果と違うのだが。 http://mevius.5ch.net/test/read.cgi/tech/1413180800/258
259: デフォルトの名無しさん [] 2018/09/16(日) 23:49:32.68 ID:SOVIz+sV とりあえず、>>198に書いてあるとおり、元のコードで再現はしてるからな その再現したコードと逆アセンブルした結果はあげとく ?-1 デフォルト設定(Release) 【コード】 #include "stdafx.h" #include <stdio.h> #include <stdint.h> #include <math.h> using namespace System; template<typename T> static double calc_norm_and_regulate(int num, T* r, bool regulate){ // <float> for debug. double norm = 0; for (
int i = 0; i < num; i++) { norm += (double)r[i] * (double)r[i]; // fprintf(stdout, "[0]0x%016llX:%.19lg\n", *(uint64_t*)&norm, norm); } fprintf(stdout, "[1]0x%016llX:%.19lg\n", *(uint64_t*)&norm, norm); norm = sqrt(norm); if (regulate) for (int i=0;i<num;i++) r[i] = (T)(r[i]/norm); return norm; } http://mevius.5ch.net/test/read.cgi/tech/1413180800/259
260: デフォルトの名無しさん [] 2018/09/16(日) 23:50:40.20 ID:SOVIz+sV ?-1 デフォルト設定(Release) 【コード】(その2) int main(array<System::String ^> ^args) { int count = 16; __int64 inputs_hex[16] = { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x1fedb1530240aa54, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x1ff0af0d95025bc3, 0x1fc9353df6af376b, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000
000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 }; double* inputs = (double*)inputs_hex; double norm = calc_norm_and_regulate(count, inputs, false); fprintf(stdout, "[2]0x%016llX:%.19lg\n", *(uint64_t*)&norm, norm); // Console::Write(String::Format("{0:F6}, 0x{1:x16}\r\n",norm, *(__int64*)&norm)); // Release build // 0.000000, 0x1ff68ddfb62221dd from IDE // 0.000000, 0x1ff68ddfb62221de from command prompt
return 0; } http://mevius.5ch.net/test/read.cgi/tech/1413180800/260
261: デフォルトの名無しさん [] 2018/09/16(日) 23:51:14.21 ID:SOVIz+sV ?-1 デフォルト設定(Release) 【実行結果】 ↓このコードの逆アセンブルコード https://ideone.com/Gf4qUQ [1]0x0007F2C44DFFF8F2:1.1053482540585106e-308 [2]0x1FF68DDFB62221DE:1.051355436595308e-154 http://mevius.5ch.net/test/read.cgi/tech/1413180800/261
262: デフォルトの名無しさん [] 2018/09/16(日) 23:54:13.85 ID:SOVIz+sV で、>>199に書いてあるとおり↓Debugビルドと同じ結果が再現された > ↓この下に(ループ内に)fprintf文を入れるだけで > ReleaseビルドとDebugビルドが同じ実行結果になることが確認できた > norm += (double)r[i] * (double)r[i]; ?-2 デフォルト設定(Release) 【コード】(その1) #include "stdafx.h" #include <stdio.h> #include <stdint.h> #include <math.h> using namespace System; template<typename T> static d
ouble calc_norm_and_regulate(int num, T* r, bool regulate){ // <float> for debug. double norm = 0; for (int i = 0; i < num; i++) { norm += (double)r[i] * (double)r[i]; fprintf(stdout, "[0]0x%016llX:%.19lg\n", *(uint64_t*)&norm, norm); } fprintf(stdout, "[1]0x%016llX:%.19lg\n", *(uint64_t*)&norm, norm); norm = sqrt(norm); if (regulate) for (int i=0;i<num;i++) r[i] = (T)(r[i]/norm)
; return norm; } http://mevius.5ch.net/test/read.cgi/tech/1413180800/262
263: デフォルトの名無しさん [] 2018/09/16(日) 23:54:58.60 ID:SOVIz+sV ?-2 デフォルト設定(Release) 【コード】(その2) int main(array<System::String ^> ^args) { int count = 16; __int64 inputs_hex[16] = { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x1fedb1530240aa54, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x1ff0af0d95025bc3, 0x1fc9353df6af376b, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000
000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 }; double* inputs = (double*)inputs_hex; double norm = calc_norm_and_regulate(count, inputs, false); fprintf(stdout, "[2]0x%016llX:%.19lg\n", *(uint64_t*)&norm, norm); // Console::Write(String::Format("{0:F6}, 0x{1:x16}\r\n",norm, *(__int64*)&norm)); // Release build // 0.000000, 0x1ff68ddfb62221dd from IDE // 0.000000, 0x1ff68ddfb62221de from command prompt
return 0; } http://mevius.5ch.net/test/read.cgi/tech/1413180800/263
264: デフォルトの名無しさん [] 2018/09/16(日) 23:56:17.88 ID:SOVIz+sV ?-2 デフォルト設定(Release) 【実行結果】 ↓このコードの逆アセンブルコード https://ideone.com/E3Nxt8 ↓実行結果を書き込めないからこっちに書き込んどいた https://ideone.com/1cky6N [1]0x0007F2C44DFFF8F1:1.1053482540585101e-308 [2]0x1FF68DDFB62221DD:1.0513554365953078e-154 以上だ http://mevius.5ch.net/test/read.cgi/tech/1413180800/264
265: デフォルトの名無しさん [sage] 2018/09/16(日) 23:58:42.66 ID:zL1WUjLu >>258 おお、そのやり方は知らなかった。大変助かった。ありがとう。 で、結果だが、>>252とは微妙に違うが、確かに拡張倍精度で計算されている。 逆アセンブル結果は、以下。 0000000e D9 EE fldz for (int i=0;i<num;i++) norm += (double)r[i] * (double)r[i]; 00000010 33 C9 xor ecx,ecx 00000012 EB 01 jmp 00000015 00000014 41 inc ecx 00000015 3B CE cmp
ecx,esi 00000017 7D 0B jge 00000024 00000019 DD 04 CF fld qword ptr [edi+ecx*8] 0000001c D9 C0 fld st(0) 0000001e DE C9 fmulp st(1),st 00000020 DE C1 faddp st(1),st 00000022 EB F0 jmp 00000014 norm = sqrt(norm); 00000024 83 EC 08 sub esp,8 00000027 DD 1C 24 fstp qword ptr [esp] 0000002a E8 49 7C F2 FF call FFF27C78 とにかく、Releaseビルドをコンソールから
起動した場合は拡張倍精度になってるのは分かった。 なら、ReleaseビルドをIDEから起動した場合は何を起動してるんだこれは? Debugビルドとも微妙にアドレス等が違うんだが。 とはいえ、これは「そもそも色々間違っている」可能性が出てきたので、もう一度全体を見直す。 明日(だけで済むとも思えないが)確認し、整理してまた投稿する。 とにかくありがとう。これはだいぶインパクトがある。(はず) http://mevius.5ch.net/test/read.cgi/tech/1413180800/265
266: デフォルトの名無しさん [sage] 2018/09/17(月) 00:49:10.27 ID:gBxGzBbQ >>265 ideとconsoleで微妙に違うバージョンのvcruntimeがロードされてるとか? process monitorで何が実行されて何がロードされてるか調べるとか? あとはwindbgから起動したら、ideとconsoleのどちらの結果と一致するのか気になる。 http://mevius.5ch.net/test/read.cgi/tech/1413180800/266
267: デフォルトの名無しさん [sage] 2018/09/17(月) 01:06:37.11 ID:+dwRu2dr >>261 だからそれは>>200と同じなんだよ。 その逆アセンブルでいうと、以下部分がメモリに出力されず、拡張倍精度で動作してるだろ。 00000281 fld qword ptr [ebp+FFFFFF14h] 00000287 fmul st,st(0) 00000289 fadd qword ptr [ebp+FFFFFF70h] 0000028f fld qword ptr [ebp+FFFFFF1Ch] 00000295 fmul st,st(0) 00000297 faddp st(1),st 00000299 fld qword ptr [ebp+FFFFFF24h] 0000029f fmul
st,st(0) 000002a1 faddp st(1),st 000002a3 fld qword ptr [ebp+FFFFFF2Ch] 000002a9 fmul st,st(0) 000002ab faddp st(1),st 000002ad fld qword ptr [ebp+FFFFFF34h] 000002b3 fmul st,st(0) 000002b5 faddp st(1),st 000002b7 fld qword ptr [ebp+FFFFFF3Ch] 000002bd fmul st,st(0) 000002bf faddp st(1),st 000002c1 fld qword ptr [ebp+FFFFFF44h] 000002c7 fmul st,st(0) 000002c9 faddp st(1),st 000002cb fld qw
ord ptr [ebp+FFFFFF4Ch] 000002d1 fmul st,st(0) 000002d3 faddp st(1),st 000002d5 fstp qword ptr [ebp+FFFFFF70h] http://mevius.5ch.net/test/read.cgi/tech/1413180800/267
メモ帳
(0/65535文字)
上
下
前
次
1-
新
書
関
写
板
覧
索
設
栞
歴
あと 47 レスあります
スレ情報
赤レス抽出
画像レス抽出
歴の未読スレ
AAサムネイル
Google検索
Wikipedia
ぬこの手
ぬこTOP
0.030s