[過去ログ]
Visual Studio 2008 Part 22 (314レス)
Visual Studio 2008 Part 22 http://mevius.5ch.net/test/read.cgi/tech/1413180800/
上
下
前
次
1-
新
通常表示
512バイト分割
レス栞
このスレッドは過去ログ倉庫に格納されています。
次スレ検索
歴削→次スレ
栞削→次スレ
過去ログメニュー
222: デフォルトの名無しさん [sage] 2018/09/16(日) 15:42:36.82 ID:haV9TZ8e >>220 いや、まだまだ興味深い。 ここで終わらせずにもっと徹底して追及すべきだ。 http://mevius.5ch.net/test/read.cgi/tech/1413180800/222
223: デフォルトの名無しさん [sage] 2018/09/16(日) 15:48:45.63 ID:zL1WUjLu >>211 それはどうやらclrでは使えないらしい。 > These functions are ignored when you use /clr (Common Language Runtime Compilation) or /clr:pure to compile > because the common language runtime (CLR) only supports the default floating-point precision. > https://msdn.microsoft.com/en-us/library/e9b52ceh.aspx とはいえ無理矢理やってみた。警告は出るがコンパイルは通る。 結果は、どこに置いても、Debug/Releaseでも、常に 0x9001f が読み出される。 ただし、これは上記の仕様からして、当てにならない。 http://mevius.5ch.net/test/read.cgi/tech/1413180800/223
224: デフォルトの名無しさん [sage] 2018/09/16(日) 15:49:44.99 ID:zL1WUjLu >>218 218のコードで試してみた結果、209で言った不安定さはなくなり、 全てにおいて 0x027f が安定して読み出せるようになった。 ただしその過程で気づいたが、 IDEから起動した場合はReleaseビルドであっても、「未初期化のスタック値」も0x00が読み出せるようだ。 どうやらこれが原因の可能性が出てきた。(はっきり言って俺のバグだが) コードは以下の通りだが、 unsigned short fpu_cw, fpu_cw_after; // fpu_getcw(&fpu_cw); double norm = calc_norm_and_regulate(count, inputs, false); fpu_getcw(&fpu_cw_after); Console::Write(String::Format("{0:D}, 0x{0:x4}\r\n",fpu_cw)); Console::Write(String::Format("{0:D}, 0x{0:x4}\r\n",fpu_cw_after)); 読み出しと書き出し(Console::Write)を両方ともコメントアウトするのが面倒なので、 色々試す際、読み出しだけコメントアウトし、不定を表示させて脳内で省略していたのだが、 IDEから起動した場合はReleaseビルドであっても必ず0x0000が表示される事に気づいた。 上記『初期化していない』 fpu_cw を Releaseビルドをコマンドプロンプトから実行: 不定 ReleaseビルドをIDEから実行: 常に0x0000 となる。 実行前にあらかじめスタック領域を0fillでもしているのか? まあこれに当たっているのなら確実に俺のバグだし、これなら辻褄は合ってしまうのだが。 http://mevius.5ch.net/test/read.cgi/tech/1413180800/224
225: デフォルトの名無しさん [sage] 2018/09/16(日) 15:51:01.50 ID:zL1WUjLu >>218 なお、逆アセンブルでコードバイトを表示させて確かめることは出来る。 正しいコードは出ている。(ただし不安定) inline void fpu_getcw(unsigned short* cw) { 00DA1540 55 push ebp 00DA1541 8B EC mov ebp,esp __asm{ fnstcw [cw]; 00DA1543 D9 7D 08 fnstcw word ptr [cw] } } 00DA1546 5D pop ebp 00DA1547 C3 ret fnstcwは D9 /7 で 7D なら [EBP+disp8] となり、 7D 08 は [EBP+08] となる。 つまりスタックポインタ+8の領域に書き戻せ、となる。 [ebp+0]は元のebpが入っているから、(pushしているので) [ebp+4]にcallの戻り値アドレス [ebp+8]にcw(第一引数)が入っていることになる。 これは正しいコードだ。 しかし再度試したが、確かに不安定だ。何故かは分からん。 inline取ってみても不安定のまま。 > そんなオペランドが使えるアセンブリ命令はx86/x64 > では存在しないので。 正直、/7の意味が分からないのだが、説明は > /digit − 0 から7 までの数字で、命令のModR/M バイトがr/m(レジスタまたはメモリ)オペランドだけを使用することを示す。 > reg フィールドには、命令のオペコードを拡張する数字が入っている。(Intelのマニュアルより) となっているのだが、これはどういう意味だ? ModR/Mバイトが全部使えるとすると [ebp+disp8]出来ることになる。そしてそのコードは出ている。 ただし、動作は怪しいのも事実。 ModR/Mの一部しか使えない、ということか? http://mevius.5ch.net/test/read.cgi/tech/1413180800/225
226: デフォルトの名無しさん [sage] 2018/09/16(日) 15:51:25.16 ID:zL1WUjLu >>218 218のコードだと、 00381002 EC in al,dx __asm{ mov edx,pCW 00381003 8B 55 08 mov edx,dword ptr [pCW] fnstcw [edx]; 00381006 D9 3A fnstcw word ptr [edx] } } 00381008 5D pop ebp 00381009 C3 ret D9 3A ならまんま fnstcw [edx] だ。 理由は分からんがこちらだと安定しているので、結果としてはこのやり方が正しい。 http://mevius.5ch.net/test/read.cgi/tech/1413180800/226
227: デフォルトの名無しさん [sage] 2018/09/16(日) 16:02:47.64 ID:haV9TZ8e >>225 をを。やはり、ある意味ではVCが間違ったアセンブリコードを出していたよ。 それだと、 fnstcw [EBP+08] という意味になってしまって、 fnstcw pCW の意味になっている。つまり: pCW = control_word; あなたが、やりたいのは、 *pCW = control_word; だったのだから、アセンブリ・コードが間違ってる。 あなたが指示したのは、 fnstcw [pCW] だった。実際に生成されたコードは、 fnstcw pCW だった。 VC のインラインアセンブラは、エラーも出さずに間違ったコードを 出すことが証明された。 これと、精度が不安定な問題とは全く別ではあるけれど。 http://mevius.5ch.net/test/read.cgi/tech/1413180800/227
228: デフォルトの名無しさん [sage] 2018/09/16(日) 16:06:05.39 ID:zL1WUjLu すまん、間違いの修正 >>224 × > どうやらこれが原因の可能性が出てきた。(はっきり言って俺のバグだが) × > まあこれに当たっているのなら確実に俺のバグだし、これなら辻褄は合ってしまうのだが。 今回は俺はあくまで俺の本番コードのデバッグを念頭に置いていて、この発言だった。 ただし>>191の再現コードで『不定スタック領域』を掴んでいるわけもなく、 一応IDE起動とコマンドプロンプト起動での挙動の違いを再現出来ているわけだから、 これだけが問題ではないのも事実だ。 俺にとっては一つ新しい知見として、 ・IDEから起動した場合、スタックが初期化されるっぽい ということが分かった。とはいえOSは0fillしてから各プロセスにメモリを与えるので、実際は、 ・コマンドプロンプト起動ならmain前に設定した続きでそのまま実行、 ・IDE起動ならmain前に色々やって0fillして実行、 或いはmain前に色々やることが多く、スタックが進み、(例えばデバッガをアタッチする為) 結果的にOSが初期化済みの領域から始動 となって違いが発生するというところか。 http://mevius.5ch.net/test/read.cgi/tech/1413180800/228
229: デフォルトの名無しさん [sage] 2018/09/16(日) 16:11:52.18 ID:haV9TZ8e >>225 >正直、/7の意味が分からないのだが、 ModRM とは、 mod reg r/m 76 543 210 のようなオペランドを指しているのだけど、/7 は、regの部分を2進数の111、 10進数の「7」にするという意味。このタイプのマシン語は、 mod ttt r/m とも書かれる。tttの部分は、命令の主幹部分(ニモニック部分)によって変わる。 普通は、レジスタ番号を入れるところに、命令の種類を表す3BITの値を入れる 仕様になっている。 あなたがインラインアセンブラでVCに出させたかったコードは、意味的には、 fnstcw [[EBP+08]] なのだが、[ ] を二重にしたようなそんなx86/x64命令は存在しないので VC がエラーも出さずに勝手に一重の fnstcw [EBP+08] にしてしまった、という事。本当は、 mov edx,[EBP+08] fnstcw [edx] というコードにしなくてはならなかったのに、VCがある意味では間違った。 これが、単独の *.asm ではなく、VC の asm {・・・} が危険な理由。 VC の asm は特に危険。 http://mevius.5ch.net/test/read.cgi/tech/1413180800/229
230: デフォルトの名無しさん [sage] 2018/09/16(日) 16:17:02.07 ID:haV9TZ8e >>228 >ただし>>191の再現コードで『不定スタック領域』を掴んでいるわけもなく、 >一応IDE起動とコマンドプロンプト起動での挙動の違いを再現出来ているわけだから、 >これだけが問題ではないのも事実だ。 そうだよ。精度が変わるのはあなたの間違いではない。スタック領域が0クリア されようがれまいが、あなたのコード自体には特に不安定さはない。 非初期化領域を参照しているコードは見当たらないし。 http://mevius.5ch.net/test/read.cgi/tech/1413180800/230
231: デフォルトの名無しさん [sage] 2018/09/16(日) 16:20:22.27 ID:haV9TZ8e 逆アセンブラ結果を見てないで言うけど、もし、sqrt() が call文で関数呼び出し されているんだったら、そこで精度の違いが出てるかもしれない。 http://mevius.5ch.net/test/read.cgi/tech/1413180800/231
232: デフォルトの名無しさん [sage] 2018/09/16(日) 16:23:20.75 ID:zL1WUjLu >>227 なるほど、了解した。 つまり、>>209は全面的に間違いで、正しくは、 ・fpu control register は 0x027F で、IDEからも正しく読めている だな。 俺がやるべきだったのは fnstcw [[cw]] なのだと思うが、これはSyntaxErrorだ。 そして、こんな命令はないから、 []内に変数を書かず、レジスタ名にしろ、ということだったのだな。 全くもって了解だ。 VCの問題ではなくて、 俺が fnstcw [cw] と書いたのが間違いで、それをそのままコードにされてしまっただけだな。 正しく書けばSyntaxErrorだったのだし。 なお fnstcw [*cw] もSyntaxErrorだ。手動で一旦レジスタに移さないと駄目だな。 全くもって>>218のコードが正しい。 http://mevius.5ch.net/test/read.cgi/tech/1413180800/232
233: デフォルトの名無しさん [sage] 2018/09/16(日) 16:35:08.59 ID:LrdaMWHl >>232 >俺がやるべきだったのは fnstcw [[cw]] なのだと思うが、これはSyntaxErrorだ。 ちょっと違う。あなたはやるべきことをちゃんと正しく、 fnstcw [cw] と書いた。しかし、cw=[ebp+8]なので、これは、 fnstcw [[ebp+8]] という「意味」になる。でも、x86/x64のマシン語にはこんな[ ]を二重にした オペランドは存在しないので、VCが無断で勝手に[ ]を一重にして、 fnstcw [ebp+8] に改変してしまった。 **(ebp+8) = control_word; としなくてはならないのに、VCが勝手に、 *(ebp+8) = control_word; としたということ。 http://mevius.5ch.net/test/read.cgi/tech/1413180800/233
234: デフォルトの名無しさん [sage] 2018/09/16(日) 16:36:04.13 ID:zL1WUjLu >>229-230 了解だ。ありがとう。 >>231 その部分の逆アセンブラは以下の通り。 普通にcallされている。(行数オーバーなので切るが) ただし、 > そこで精度の違いが出てるかもしれない との繋がりがよくからない。 sqrt()でcallされると、スタックが改変される。おそらくデータ依存か? なら未初期化のスタックを掴みに行っているコードが有ればバグる。 ただし今回の『再現コード』はこの限りではない。 (俺の本番コードはさておき) http://mevius.5ch.net/test/read.cgi/tech/1413180800/234
235: デフォルトの名無しさん [sage] 2018/09/16(日) 16:37:19.30 ID:zL1WUjLu >>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] http://mevius.5ch.net/test/read.cgi/tech/1413180800/235
236: デフォルトの名無しさん [sage] 2018/09/16(日) 16:37:34.94 ID:zL1WUjLu >>231 逆アセンブラ(続き) if (regulate) for (int i=0;i<num;i++) r[i] = (T)(r[i]/norm); 00000078 0F B6 45 08 movzx eax,byte ptr [ebp+8] 0000007c 85 C0 test eax,eax 0000007e 74 25 je 000000A5 00000080 33 D2 xor edx,edx 00000082 89 55 EC mov dword ptr [ebp-14h],edx 00000085 90 nop 00000086 EB 03 jmp 0000008B 00000088 FF 45 EC inc dword ptr [ebp-14h] 0000008b 8B 45 EC mov eax,dword ptr [ebp-14h] 0000008e 3B 45 FC cmp eax,dword ptr [ebp-4] 00000091 7D 12 jge 000000A5 00000093 8B 45 F8 mov eax,dword ptr [ebp-8] 00000096 8B 55 EC mov edx,dword ptr [ebp-14h] 00000099 DD 45 F0 fld qword ptr [ebp-10h] 0000009c DC 3C D0 fdivr qword ptr [eax+edx*8] 0000009f DD 1C D0 fstp qword ptr [eax+edx*8] 000000a2 90 nop 000000a3 EB E3 jmp 00000088 return norm; 000000a5 DD 45 F0 fld qword ptr [ebp-10h] 000000a8 DD 5D E0 fstp qword ptr [ebp-20h] http://mevius.5ch.net/test/read.cgi/tech/1413180800/236
237: デフォルトの名無しさん [sage] 2018/09/16(日) 16:40:36.14 ID:LrdaMWHl >>234 よく見ると、最小(?)の実験コードでは sqrt() が使われていなかった。 スマン。 http://mevius.5ch.net/test/read.cgi/tech/1413180800/237
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 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 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 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] 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 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 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 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] 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
メモ帳
(0/65535文字)
上
下
前
次
1-
新
書
関
写
板
覧
索
設
栞
歴
あと 63 レスあります
スレ情報
赤レス抽出
画像レス抽出
歴の未読スレ
AAサムネイル
Google検索
Wikipedia
ぬこの手
ぬこTOP
0.009s