■公式
ttp://www.microsoft.com/japan/msdn/vstudio/default.aspx
■前スレ
Visual Studio 2008 Part 21
http://peace.2ch.net/test/read.cgi/tech/1290969016/
■リンク
Visual Studio 2008に搭載された17の新機能
ttp://www.atmarkit.co.jp/fdotnet/special/visualstudio2008_01/visualstudio2008_01_01.html
5000個のバグと戦った、MSが「Visual Studio 2008」RTM出荷
ttp://www.atmarkit.co.jp/news/200711/20/vs.html
■関連
Visual Studio 2013 part4
http://peace.2ch.net/test/read.cgi/tech/1404333757/
Visual Studio 2012 Part8
http://peace.2ch.net/test/read.cgi/tech/1392639689/
Visual Studio 2010 Part21
http://peace.2ch.net/test/read.cgi/tech/1412136476/
Visual Studio 2005 Part 27
http://peace.2ch.net/test/read.cgi/tech/1291513609/
その他テンプレ>>2-5
Visual Studio 2008 Part 22
■ このスレッドは過去ログ倉庫に格納されています
2014/10/13(月) 15:13:20.18ID:yFRqmPNp
264デフォルトの名無しさん
2018/09/16(日) 23:56:17.88ID:SOVIz+sV B-2 デフォルト設定(Release) 【実行結果】
↓このコードの逆アセンブルコード
https://ideone.com/E3Nxt8
↓実行結果を書き込めないからこっちに書き込んどいた
https://ideone.com/1cky6N
[1]0x0007F2C44DFFF8F1:1.1053482540585101e-308
[2]0x1FF68DDFB62221DD:1.0513554365953078e-154
以上だ
↓このコードの逆アセンブルコード
https://ideone.com/E3Nxt8
↓実行結果を書き込めないからこっちに書き込んどいた
https://ideone.com/1cky6N
[1]0x0007F2C44DFFF8F1:1.1053482540585101e-308
[2]0x1FF68DDFB62221DD:1.0513554365953078e-154
以上だ
265デフォルトの名無しさん
2018/09/16(日) 23:58:42.66ID: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ビルドとも微妙にアドレス等が違うんだが。
とはいえ、これは「そもそも色々間違っている」可能性が出てきたので、もう一度全体を見直す。
明日(だけで済むとも思えないが)確認し、整理してまた投稿する。
とにかくありがとう。これはだいぶインパクトがある。(はず)
おお、そのやり方は知らなかった。大変助かった。ありがとう。
で、結果だが、>>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ビルドとも微妙にアドレス等が違うんだが。
とはいえ、これは「そもそも色々間違っている」可能性が出てきたので、もう一度全体を見直す。
明日(だけで済むとも思えないが)確認し、整理してまた投稿する。
とにかくありがとう。これはだいぶインパクトがある。(はず)
266デフォルトの名無しさん
2018/09/17(月) 00:49:10.27ID:gBxGzBbQ >>265
ideとconsoleで微妙に違うバージョンのvcruntimeがロードされてるとか?
process monitorで何が実行されて何がロードされてるか調べるとか?
あとはwindbgから起動したら、ideとconsoleのどちらの結果と一致するのか気になる。
ideとconsoleで微妙に違うバージョンのvcruntimeがロードされてるとか?
process monitorで何が実行されて何がロードされてるか調べるとか?
あとはwindbgから起動したら、ideとconsoleのどちらの結果と一致するのか気になる。
267デフォルトの名無しさん
2018/09/17(月) 01:06:37.11ID:+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 qword ptr [ebp+FFFFFF4Ch]
000002d1 fmul st,st(0)
000002d3 faddp st(1),st
000002d5 fstp qword ptr [ebp+FFFFFF70h]
だからそれは>>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 qword ptr [ebp+FFFFFF4Ch]
000002d1 fmul st,st(0)
000002d3 faddp st(1),st
000002d5 fstp qword ptr [ebp+FFFFFF70h]
268デフォルトの名無しさん
2018/09/17(月) 01:07:41.74ID:+dwRu2dr >>261(続き)
これは少なくとも「ループ回数が8の倍数である」事がコンパイラに見えないと出来ない最適化だ。
そうでなければ、例えばループ回数が6回や14回の時に、
最初の1回だけ 0299 に飛び込んで始める(頭の2回をスキップする)コードが必要になるが、
それは出てないだろ。
(そもそもこのアンローリングがx86的に意味があるのかも疑問だが)
一般的に、可変回数ループを展開すると、必ず上記の端切れ処理(キリが良くないときの処理)が必要になる。
だから「可変」だと確定しているのなら普通は展開しない。
つまり、一般的には、別関数でループ回数が引数で与えられてたら、その最適化はかからない。
今回ヒットするデータが偶々16回ループだっただけで、
俺の本番コードは可変で用いている為、
このようなアンローリングはされてない。(と思ってる。ただし265の通りもう一度確認必要)
こちらではデフォでそこまで最適化がかからないのでそちらの状況はよく分からないが、
その最適化がかかってるのなら、俺の本番コードとは違う状況で動いていることになる。(はず)
だから俺はその最適化がかからない範囲で議論してる。
それが俺が最初から別関数にしてた理由。(というか元のコードが別関数だからだが)
てゆうかマジでそれデフォのままか?
もしかして俺の環境がおかしくて、全く最適化されてないコードが出てる?
これは少なくとも「ループ回数が8の倍数である」事がコンパイラに見えないと出来ない最適化だ。
そうでなければ、例えばループ回数が6回や14回の時に、
最初の1回だけ 0299 に飛び込んで始める(頭の2回をスキップする)コードが必要になるが、
それは出てないだろ。
(そもそもこのアンローリングがx86的に意味があるのかも疑問だが)
一般的に、可変回数ループを展開すると、必ず上記の端切れ処理(キリが良くないときの処理)が必要になる。
だから「可変」だと確定しているのなら普通は展開しない。
つまり、一般的には、別関数でループ回数が引数で与えられてたら、その最適化はかからない。
今回ヒットするデータが偶々16回ループだっただけで、
俺の本番コードは可変で用いている為、
このようなアンローリングはされてない。(と思ってる。ただし265の通りもう一度確認必要)
こちらではデフォでそこまで最適化がかからないのでそちらの状況はよく分からないが、
その最適化がかかってるのなら、俺の本番コードとは違う状況で動いていることになる。(はず)
だから俺はその最適化がかからない範囲で議論してる。
それが俺が最初から別関数にしてた理由。(というか元のコードが別関数だからだが)
てゆうかマジでそれデフォのままか?
もしかして俺の環境がおかしくて、全く最適化されてないコードが出てる?
269247
2018/09/17(月) 01:12:11.55ID:yaPtorLJ 今、戻った。
席を離れて思ったが、多分、C++/CLI の場合、IDEでコンパイル後、
exeファイルになっても、unmanaged コード部分以外は、本質的には
.NETの共通中間言語(CIL、MSIL)になるだけで、x86のマシン語には
なってないと思う。一方、昔ながらの本当のC++では、exeの中身は、
本質的には、x86のマシン語が入っていた。
C++/CLIの場合、作成されたexeは、起動時に、中間言語がx86の
マシン語に直されてから実行される。その際、最適化の関係で、
どう直されるかが必ずしも一定していない。だから、IDEからの起動と、
コマンドラインからの起動で異なったx86命令に直されてしまう
のかも知れない。
出来たx86コードが、良く最適化された場合、x87 fpu命令を長きに
渡ってメモリに書き戻さずに、st(0)〜st(7)のレジスタ上で演算し
続けられることになる。その場合、80BITの精度で計算される
期間が長くなる。
一方、x87 fpu命令に関する最適化が少し悪いか、悪くなくても命令の
使い方が変わってしまうと、80BIT(拡張double)から64BIT(double)へ
直されるタイミングや回数が変わる。
この両者では結果の精度が変わってくる。前者の方が後者より僅か
に精度が高くなる。
席を離れて思ったが、多分、C++/CLI の場合、IDEでコンパイル後、
exeファイルになっても、unmanaged コード部分以外は、本質的には
.NETの共通中間言語(CIL、MSIL)になるだけで、x86のマシン語には
なってないと思う。一方、昔ながらの本当のC++では、exeの中身は、
本質的には、x86のマシン語が入っていた。
C++/CLIの場合、作成されたexeは、起動時に、中間言語がx86の
マシン語に直されてから実行される。その際、最適化の関係で、
どう直されるかが必ずしも一定していない。だから、IDEからの起動と、
コマンドラインからの起動で異なったx86命令に直されてしまう
のかも知れない。
出来たx86コードが、良く最適化された場合、x87 fpu命令を長きに
渡ってメモリに書き戻さずに、st(0)〜st(7)のレジスタ上で演算し
続けられることになる。その場合、80BITの精度で計算される
期間が長くなる。
一方、x87 fpu命令に関する最適化が少し悪いか、悪くなくても命令の
使い方が変わってしまうと、80BIT(拡張double)から64BIT(double)へ
直されるタイミングや回数が変わる。
この両者では結果の精度が変わってくる。前者の方が後者より僅か
に精度が高くなる。
271デフォルトの名無しさん
2018/09/17(月) 01:24:06.04ID:yaPtorLJ >>257
>なおILSpy、グダグダ言わずに試してみたが、
>当たり前だがmanaged code だとILが出る(x86ではない)ので、
>俺って根本的に間違ってたかも?
>今までx86のアセンブラで議論してたけど、これって .NET アプリには同梱されていないというオチ?
やはり、managed code部分は、x86命令では無く、ILにコンパイルされていて、
普通のC++とは違ってたんだ。
>なおILSpy、グダグダ言わずに試してみたが、
>当たり前だがmanaged code だとILが出る(x86ではない)ので、
>俺って根本的に間違ってたかも?
>今までx86のアセンブラで議論してたけど、これって .NET アプリには同梱されていないというオチ?
やはり、managed code部分は、x86命令では無く、ILにコンパイルされていて、
普通のC++とは違ってたんだ。
272デフォルトの名無しさん
2018/09/17(月) 01:30:31.16ID:yaPtorLJ >calc_norm_and_regulateをunmanaged関数にすると、違いはなくなる。
>(Releaseビルドの`をコマンドプロンプトで起動した際にも、****ddの結果となる)
やはり。
unmanaged関数の場合は、CIL(MSIL)ではなく、exeの段階で既に
x86マシン語に直されたものが格納されるんだろう。だとすると、起動方法に
関係なく、少なくともその部分に関しては、x87 fpu命令の使われ方が
全く同じになる。callしたsqrt()関数の中は除いて。
>(Releaseビルドの`をコマンドプロンプトで起動した際にも、****ddの結果となる)
やはり。
unmanaged関数の場合は、CIL(MSIL)ではなく、exeの段階で既に
x86マシン語に直されたものが格納されるんだろう。だとすると、起動方法に
関係なく、少なくともその部分に関しては、x87 fpu命令の使われ方が
全く同じになる。callしたsqrt()関数の中は除いて。
273デフォルトの名無しさん
2018/09/17(月) 01:37:20.55ID:dj7qSZnZ274デフォルトの名無しさん
2018/09/17(月) 02:03:16.26ID:yaPtorLJ はっきり書いてある。managed code は、起動時にJITコンパイルされる。
だから、どんなマシン語に置き換わるかが、コンパイルしただけでは
まだ完全には決定されてない。
https://en.wikipedia.org/wiki/Managed_code
Drawbacks include slower startup speed (the managed code must be JIT
compiled by the VM) and generally increased use of system resources
on any machine that is executing the code.
managed code は、VMによって、JIT コンパイルされないといけないので、
起動速度が遅くなり、かつ、一般的に、システム・リソースの使用が増える。
だから、どんなマシン語に置き換わるかが、コンパイルしただけでは
まだ完全には決定されてない。
https://en.wikipedia.org/wiki/Managed_code
Drawbacks include slower startup speed (the managed code must be JIT
compiled by the VM) and generally increased use of system resources
on any machine that is executing the code.
managed code は、VMによって、JIT コンパイルされないといけないので、
起動速度が遅くなり、かつ、一般的に、システム・リソースの使用が増える。
275デフォルトの名無しさん
2018/09/17(月) 02:49:02.18ID:dj7qSZnZ 普通のコンソールアプリケーション(CLRじゃないほう)でも
同じコードで普通にまったく同じように再現するワケだが
ホントなキミラはなにを頭悪いことばっかりいってんの?
実行結果だけははっといてやるが
同じコードで普通にまったく同じように再現するワケだが
ホントなキミラはなにを頭悪いことばっかりいってんの?
実行結果だけははっといてやるが
276デフォルトの名無しさん
2018/09/17(月) 02:50:12.89ID:dj7qSZnZ C-1 デフォルト設定(Release) 【コード】(その1)
#include "stdafx.h"
#include <stdio.h>
#include <stdint.h>
#include <math.h>
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;
}
#include "stdafx.h"
#include <stdio.h>
#include <stdint.h>
#include <math.h>
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;
}
277デフォルトの名無しさん
2018/09/17(月) 02:50:37.91ID:dj7qSZnZ C-1 デフォルト設定(Release) 【コード】(その2)
int _tmain(int argc, _TCHAR* argv[])
{
int count = 16;
__int64 inputs_hex[16] = {
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x1fedb1530240aa54,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x1ff0af0d95025bc3,
0x1fc9353df6af376b, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 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);
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
int count = 16;
__int64 inputs_hex[16] = {
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x1fedb1530240aa54,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x1ff0af0d95025bc3,
0x1fc9353df6af376b, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 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);
return 0;
}
278デフォルトの名無しさん
2018/09/17(月) 02:51:12.35ID:dj7qSZnZ C-1 デフォルト設定(Release) 【実行結果】
↓このコードの逆アセンブルコード
https://ideone.com/Dqqn6J
[1]0x0007F2C44DFFF8F2:1.1053482540585106e-308
[2]0x1FF68DDFB62221DE:1.051355436595308e-154
↓このコードの逆アセンブルコード
https://ideone.com/Dqqn6J
[1]0x0007F2C44DFFF8F2:1.1053482540585106e-308
[2]0x1FF68DDFB62221DE:1.051355436595308e-154
279デフォルトの名無しさん
2018/09/17(月) 02:51:53.99ID:dj7qSZnZ C-2 デフォルト設定(Release) 【コード】(その1)
#include "stdafx.h"
#include <stdio.h>
#include <stdint.h>
#include <math.h>
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;
}
#include "stdafx.h"
#include <stdio.h>
#include <stdint.h>
#include <math.h>
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;
}
280デフォルトの名無しさん
2018/09/17(月) 02:52:10.55ID:dj7qSZnZ C-2 デフォルト設定(Release) 【コード】(その2)
int _tmain(int argc, _TCHAR* argv[])
{
int count = 16;
__int64 inputs_hex[16] = {
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x1fedb1530240aa54,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x1ff0af0d95025bc3,
0x1fc9353df6af376b, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 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);
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
int count = 16;
__int64 inputs_hex[16] = {
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x1fedb1530240aa54,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x1ff0af0d95025bc3,
0x1fc9353df6af376b, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 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);
return 0;
}
281デフォルトの名無しさん
2018/09/17(月) 02:52:25.20ID:dj7qSZnZ C-2 デフォルト設定(Release) 【実行結果】
↓このコードの逆アセンブルコード
https://ideone.com/5OaUe6
↓実行結果を書き込めないからこっちに書き込んどいた
https://ideone.com/FFW0P0
[1]0x0007F2C44DFFF8F1:1.1053482540585101e-308
[2]0x1FF68DDFB62221DD:1.0513554365953078e-154
↓このコードの逆アセンブルコード
https://ideone.com/5OaUe6
↓実行結果を書き込めないからこっちに書き込んどいた
https://ideone.com/FFW0P0
[1]0x0007F2C44DFFF8F1:1.1053482540585101e-308
[2]0x1FF68DDFB62221DD:1.0513554365953078e-154
282デフォルトの名無しさん
2018/09/17(月) 02:53:45.62ID:dj7qSZnZ C-2 デフォルト設定(Release) 【コード】(その1)
#include "stdafx.h"
#include <stdio.h>
#include <stdint.h>
#include <math.h>
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;
}
#include "stdafx.h"
#include <stdio.h>
#include <stdint.h>
#include <math.h>
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;
}
284デフォルトの名無しさん
2018/09/17(月) 02:57:46.48ID:dj7qSZnZ285デフォルトの名無しさん
2018/09/17(月) 09:44:34.76ID:yu1Dprt2 >>284
同一のreleaseをコンソールで実行するかデバッガで実行するかで結果が異なるのはなぜだろう。
という話をしていたのであって、
debug/releaseで別の結果になることを問題にしているのではないです。
同一のreleaseをコンソールで実行するかデバッガで実行するかで結果が異なるのはなぜだろう。
という話をしていたのであって、
debug/releaseで別の結果になることを問題にしているのではないです。
286デフォルトの名無しさん
2018/09/17(月) 10:25:22.39ID:+dwRu2dr >>191がコンソール起動とIDE起動で挙動が異なる理由は分かりました。
ありがとう。
結論はつまり以下だ。
> JIT の最適化とデバッグ(抜粋)
> マネージ アプリケーションをデバッグするとき、Visual Studio では、既定で、
> ジャスト イン タイム (JIT: Just-In-Time) コードの最適化が省略されています。
> 最適化されたコードをデバッグするのは困難であるため、
> 最適化されたコードで発生するバグが、非最適化バージョンでは再現しないときにのみお勧めします。
> JIT 最適化は、Visual Studio の [モジュールの読み込み中に JIT 最適化を抑制する] オプションで制御されます。
> 実行中のプロセスにアタッチする場合、既に読み込まれ、JIT でコンパイルされ、
> 最適化されているコードが含まれることがあります。
> このようなコードの場合、[モジュールの読み込み中に JIT 最適化を抑制する] オプションの影響はありません。
> https://msdn.microsoft.com/ja-jp/library/ms241594.aspx
確かにこのオプションで直った。
ありがとう。
結論はつまり以下だ。
> JIT の最適化とデバッグ(抜粋)
> マネージ アプリケーションをデバッグするとき、Visual Studio では、既定で、
> ジャスト イン タイム (JIT: Just-In-Time) コードの最適化が省略されています。
> 最適化されたコードをデバッグするのは困難であるため、
> 最適化されたコードで発生するバグが、非最適化バージョンでは再現しないときにのみお勧めします。
> JIT 最適化は、Visual Studio の [モジュールの読み込み中に JIT 最適化を抑制する] オプションで制御されます。
> 実行中のプロセスにアタッチする場合、既に読み込まれ、JIT でコンパイルされ、
> 最適化されているコードが含まれることがあります。
> このようなコードの場合、[モジュールの読み込み中に JIT 最適化を抑制する] オプションの影響はありません。
> https://msdn.microsoft.com/ja-jp/library/ms241594.aspx
確かにこのオプションで直った。
287デフォルトの名無しさん
2018/09/17(月) 10:25:48.51ID:+dwRu2dr その他諸々、話を整理すると、以下となる。(ソースは>>191参照)
1. managedコードではMSILが出力され、x86コードは含まれていない。
2. 起動時、MSILはJITされ、x86コードに落とされる。
3. このため、mainの1行目でブレークポイントで止め、calc_norm_and_regulateの逆アセンブルを見ようとしても、
IDE上で「逆アセンブルを表示できません。式がまだネイティブ マシン コードに翻訳されていません。」と出る。
これはmainの1行目に System::Diagnostics::Debugger::Launch(); を入れたときも同様。
4. そしてこのJITに関して、上記IDE中の 『[モジュールの読み込み中に JIT 最適化を抑制する] オプション』 が効いてくる。
規定ではオフ、つまり、ReleaseビルドでもIDE起動ならJIT最適化は抑制される。
これがfld/fmul/fadd/fstpのループコードになる理由。
これをオンにすれば、確かにReleaseビルドIDE起動でも、
fld/fmul/faddのループコードとなり、コマンドプロンプト起動と同じ結果になることは確認した。
5. 上記では表現が微妙だが、JIT最適化をするかどうかは読み込まれるときに決まるらしい。
したがって、Releaseビルドを起動後にアタッチした場合は通常通り最適化され、
IDEからReleaseビルドを起動した場合は『既定では』最適化が抑制されてしまう。
これがIDE起動とコマンドプロンプト起動で挙動が異なった原因。
上記、『[モジュールの読み込み中に JIT 最適化を抑制する]』のチェックを外せば、直った。
6. おそらくこのオプションはソリューション毎ではなく、IDEのインストール毎なんだと思う。
(ソリューション毎のオプションはプロジェクトのプロパティにあり、場所が違う)
だからその人の環境によっては最初からオフにしている人がいたかも?
これが再現実験をしてくれた人たちと微妙に結果が異なったりした原因か?
これで>>191についての疑問は解消した。(はず)
俺の本番コードについては再度確認し、また報告する。
1. managedコードではMSILが出力され、x86コードは含まれていない。
2. 起動時、MSILはJITされ、x86コードに落とされる。
3. このため、mainの1行目でブレークポイントで止め、calc_norm_and_regulateの逆アセンブルを見ようとしても、
IDE上で「逆アセンブルを表示できません。式がまだネイティブ マシン コードに翻訳されていません。」と出る。
これはmainの1行目に System::Diagnostics::Debugger::Launch(); を入れたときも同様。
4. そしてこのJITに関して、上記IDE中の 『[モジュールの読み込み中に JIT 最適化を抑制する] オプション』 が効いてくる。
規定ではオフ、つまり、ReleaseビルドでもIDE起動ならJIT最適化は抑制される。
これがfld/fmul/fadd/fstpのループコードになる理由。
これをオンにすれば、確かにReleaseビルドIDE起動でも、
fld/fmul/faddのループコードとなり、コマンドプロンプト起動と同じ結果になることは確認した。
5. 上記では表現が微妙だが、JIT最適化をするかどうかは読み込まれるときに決まるらしい。
したがって、Releaseビルドを起動後にアタッチした場合は通常通り最適化され、
IDEからReleaseビルドを起動した場合は『既定では』最適化が抑制されてしまう。
これがIDE起動とコマンドプロンプト起動で挙動が異なった原因。
上記、『[モジュールの読み込み中に JIT 最適化を抑制する]』のチェックを外せば、直った。
6. おそらくこのオプションはソリューション毎ではなく、IDEのインストール毎なんだと思う。
(ソリューション毎のオプションはプロジェクトのプロパティにあり、場所が違う)
だからその人の環境によっては最初からオフにしている人がいたかも?
これが再現実験をしてくれた人たちと微妙に結果が異なったりした原因か?
これで>>191についての疑問は解消した。(はず)
俺の本番コードについては再度確認し、また報告する。
288デフォルトの名無しさん
2018/09/17(月) 10:28:21.54ID:dj7qSZnZ 同じリリースビルドで
結果がかわってんのになにいってんの?
fprintf入れるだけで
リリースビルドで結果が変わる
結果がかわってんのになにいってんの?
fprintf入れるだけで
リリースビルドで結果が変わる
289デフォルトの名無しさん
2018/09/17(月) 10:31:16.66ID:dj7qSZnZ やはり低学歴知恵遅れは
結果が意味するところが分かってないわ。。。
結果が意味するところが分かってないわ。。。
290デフォルトの名無しさん
2018/09/17(月) 10:32:49.39ID:dj7qSZnZ ちなみにオレがあげた結果は
すべてリリースビルドの結果だからな
デバッグビルドの結果なんかあげても
意味ないからな
すべてリリースビルドの結果だからな
デバッグビルドの結果なんかあげても
意味ないからな
291デフォルトの名無しさん
2018/09/17(月) 10:38:00.02ID:dj7qSZnZ CLRのケースもCLRでない普通のexeのケースでも
結果はまったく同じだからな
しかもすべてリリースビルドで
おきてる誤差までぴったり一致してる
結果はまったく同じだからな
しかもすべてリリースビルドで
おきてる誤差までぴったり一致してる
292デフォルトの名無しさん
2018/09/17(月) 10:52:24.35ID:+dwRu2dr >>288
お前は相変わらず理解してないな。
80bit(拡張倍精度)と64bit(倍精度)の演算で桁落ちが異なり、結果が異なるのは当然なんだよ。
問題は同じバイナリの癖に何故起動方法によって異なるのか?だったんだ。
理由はMSILだからだ。
MSILはCLR上でJITされ、x86コードに落とされる。
このときにJIT最適化がかかれば、拡張倍精度(を保ったまま)のコードになるし、
最適化がかからず毎回メモリに書き戻していれば、倍精度のコードになる。
.NETにおける同一バイナリってのは、同一MSILという意味であって、同一x86機械語という意味ではない。
だから、確かに同一バイナリを掴んでいたが、起動方法によって結果が異なっていたんだよ。
(VSがデバッグ用に意図的にそういう仕様にしていただけ。俺はそれを知らなかった)
君のコードについては、
いちいちfprintする場合はdouble(倍精度)が毎回必要になるから、
コンパイラはその部分での拡張倍精度でのループを断念し、
結果的にそのループが倍精度で回っているだけのこと。
もし仮にCが拡張倍精度型 ExDouble を持っていたとして、printfもそれに対応していれば、
もしかするとその毎回printfするコードでも拡張倍精度で回っていたかもしれん。
勿論手動でそういうコードのすることも可能だ。
そこはコンパイラがどう判断したのかでしかなく、あまり詰めても意味がない。
お前は相変わらず理解してないな。
80bit(拡張倍精度)と64bit(倍精度)の演算で桁落ちが異なり、結果が異なるのは当然なんだよ。
問題は同じバイナリの癖に何故起動方法によって異なるのか?だったんだ。
理由はMSILだからだ。
MSILはCLR上でJITされ、x86コードに落とされる。
このときにJIT最適化がかかれば、拡張倍精度(を保ったまま)のコードになるし、
最適化がかからず毎回メモリに書き戻していれば、倍精度のコードになる。
.NETにおける同一バイナリってのは、同一MSILという意味であって、同一x86機械語という意味ではない。
だから、確かに同一バイナリを掴んでいたが、起動方法によって結果が異なっていたんだよ。
(VSがデバッグ用に意図的にそういう仕様にしていただけ。俺はそれを知らなかった)
君のコードについては、
いちいちfprintする場合はdouble(倍精度)が毎回必要になるから、
コンパイラはその部分での拡張倍精度でのループを断念し、
結果的にそのループが倍精度で回っているだけのこと。
もし仮にCが拡張倍精度型 ExDouble を持っていたとして、printfもそれに対応していれば、
もしかするとその毎回printfするコードでも拡張倍精度で回っていたかもしれん。
勿論手動でそういうコードのすることも可能だ。
そこはコンパイラがどう判断したのかでしかなく、あまり詰めても意味がない。
293デフォルトの名無しさん
2018/09/17(月) 10:54:19.52ID:+dwRu2dr × fprint
○ printf
まあ、分かると思いますが
○ printf
まあ、分かると思いますが
294デフォルトの名無しさん
2018/09/17(月) 10:57:31.99ID:dj7qSZnZ で、最適化されてるかされてないかすら
いまのいままで気付くことすらできない
そして気付く方法すらわからなかったわけか
うあわ
頭わるう。。。
キミ、プログラムくむの向いてないわ
いまのいままで気付くことすらできない
そして気付く方法すらわからなかったわけか
うあわ
頭わるう。。。
キミ、プログラムくむの向いてないわ
295デフォルトの名無しさん
2018/09/17(月) 10:58:47.63ID:dj7qSZnZ 問題の切り分けができない人は
プログラムはくめない
コレは定説だからな
プログラムはくめない
コレは定説だからな
296デフォルトの名無しさん
2018/09/17(月) 11:09:05.96ID:ivGPGa/P297デフォルトの名無しさん
2018/09/17(月) 12:34:14.16ID:yaPtorLJ 個人的には、C++やx87 FPUは割と知識があったけど、.NET関連は余り追いかけてなかったので、気づくのが遅れた。
managedコード、unmanagedコードについて、今回初めて調べてみたくらいだし。
managedコード、unmanagedコードについて、今回初めて調べてみたくらいだし。
298デフォルトの名無しさん
2018/09/17(月) 12:53:34.77ID:yaPtorLJ299デフォルトの名無しさん
2018/09/17(月) 13:39:23.91ID:F2vzl5VC 最初に指摘されたことだろうに。
アセンブラレベルで精度や効率に介入したきゃ.netなんて使うな、なんて分かりきったこと。
アセンブラレベルで精度や効率に介入したきゃ.netなんて使うな、なんて分かりきったこと。
300デフォルトの名無しさん
2018/09/17(月) 14:58:46.52ID:zCVYDMXL エディタ使ってるとたまに Intellisense機能が効かないときがあるんだが
あれなんなの?
中間ファイルとか消せば直るの?
あれなんなの?
中間ファイルとか消せば直るの?
301デフォルトの名無しさん
2018/09/17(月) 17:03:46.83ID:+dwRu2dr >>300
はい。よく壊れます。
> [C++] There is an issue with the .ncb file
> Close the solution.
> Delete the . ncb file.
> Reopen the solution.
> Reopening the solution creates a new . ncb file.
> https://msdn.microsoft.com/ja-jp/library/ks1ka3t6(v=vs.110)
はい。よく壊れます。
> [C++] There is an issue with the .ncb file
> Close the solution.
> Delete the . ncb file.
> Reopen the solution.
> Reopening the solution creates a new . ncb file.
> https://msdn.microsoft.com/ja-jp/library/ks1ka3t6(v=vs.110)
302デフォルトの名無しさん
2018/09/17(月) 17:17:56.66ID:zCVYDMXL303デフォルトの名無しさん
2018/09/17(月) 18:30:58.83ID:+dwRu2dr さて俺の本番コード、以下のようだ。
疑問は解消した。協力してくれた皆様ありがとう。
◎:拡張倍精度、○:倍精度、として、(ソースは>>191参照)
・Releaseビルドをコマンドプロンプトから起動→◎積和、◎平方根
・Debugビルドをコマンドプロンプトから起動→◎積和、○平方根
・IDEから起動→○積和、○平方根
これで3種類出来上がってた。
(なお、>>166内バイナリをアタッチした際の「AまたはC」は、「AまたはB」の間違い)
そしてIDE上で『[モジュールの読み込み中に JIT 最適化を抑制する]』を変更すると、
確かにRelease/Debugの2種類に絞れる。
Debugだからといって、全く最適化がかからないわけでもないようだ。
(1行内なら最適化がかかる?)
参考に、Releaseビルドの該当部分の逆アセンブルは以下。
積和が拡張倍精度で行われ、そのまま fsqrt で平方根が取られる。
(関数ごとインライン化されているのでアドレスが中途半端だが)
double retval = calc_norm_and_regulate(count, vec, false);
0000003e fldz
00000040 xor edx,edx
00000042 test esi,esi
00000044 jle 00000056
00000046 lea eax,[esp+28h]
0000004a fld qword ptr [eax+edx*8]
0000004d fmul st(0),st
0000004f faddp st(1),st
00000051 inc edx
00000052 cmp edx,esi
00000054 jl 00000046
00000056 fsqrt
00000058 fstp qword ptr [esp+10h]
疑問は解消した。協力してくれた皆様ありがとう。
◎:拡張倍精度、○:倍精度、として、(ソースは>>191参照)
・Releaseビルドをコマンドプロンプトから起動→◎積和、◎平方根
・Debugビルドをコマンドプロンプトから起動→◎積和、○平方根
・IDEから起動→○積和、○平方根
これで3種類出来上がってた。
(なお、>>166内バイナリをアタッチした際の「AまたはC」は、「AまたはB」の間違い)
そしてIDE上で『[モジュールの読み込み中に JIT 最適化を抑制する]』を変更すると、
確かにRelease/Debugの2種類に絞れる。
Debugだからといって、全く最適化がかからないわけでもないようだ。
(1行内なら最適化がかかる?)
参考に、Releaseビルドの該当部分の逆アセンブルは以下。
積和が拡張倍精度で行われ、そのまま fsqrt で平方根が取られる。
(関数ごとインライン化されているのでアドレスが中途半端だが)
double retval = calc_norm_and_regulate(count, vec, false);
0000003e fldz
00000040 xor edx,edx
00000042 test esi,esi
00000044 jle 00000056
00000046 lea eax,[esp+28h]
0000004a fld qword ptr [eax+edx*8]
0000004d fmul st(0),st
0000004f faddp st(1),st
00000051 inc edx
00000052 cmp edx,esi
00000054 jl 00000046
00000056 fsqrt
00000058 fstp qword ptr [esp+10h]
304デフォルトの名無しさん
2018/09/19(水) 17:24:44.24ID:GzaYiinu VC++2008だけど、突然一部のファイルだけブレークポイントが入らなくなった・・・
.ncb消したり、そのプロジェクトだけリビルドしたけど直らない
全リビルドすればおk?
.ncb消したり、そのプロジェクトだけリビルドしたけど直らない
全リビルドすればおk?
305デフォルトの名無しさん
2018/09/19(水) 18:59:08.26ID:KTUM/Tgt >>304
根本的な解決策とは違うが
「ブレークポイントは現在の設定ではヒットしません。ソースコードが元のバージョンと異なります。」
なら
[オプション] の[デバッグ]から[元のバージョンと完全に一致するソース ファイルを必要とする] をオフで
根本的な解決策とは違うが
「ブレークポイントは現在の設定ではヒットしません。ソースコードが元のバージョンと異なります。」
なら
[オプション] の[デバッグ]から[元のバージョンと完全に一致するソース ファイルを必要とする] をオフで
306デフォルトの名無しさん
2018/09/20(木) 12:44:39.12ID:rLmEYUhk307デフォルトの名無しさん
2019/06/19(水) 14:12:16.93ID:Yoy0IPRe お、おう
308デフォルトの名無しさん
2019/10/04(金) 14:14:25.88ID:gozwERy2 C++ CLRのWindowsフォームアプリ作ってると、
イベントとか記入するときインデントがおかしい(スペースが1つ付く)んですが、
これを直す方法ってありますか?
イベントとか記入するときインデントがおかしい(スペースが1つ付く)んですが、
これを直す方法ってありますか?
309デフォルトの名無しさん
2019/10/06(日) 21:09:30.88ID:xhkeezXX テンプレート特殊化ってVisualC++2008 SP1 ではできないですか?
310デフォルトの名無しさん
2019/10/06(日) 21:48:55.66ID:xhkeezXX311デフォルトの名無しさん
2021/04/20(火) 20:00:45.05ID:rVJPu0WM わからないので教えてください。
シリアル通信をするプログラムを作りたく、
VS2008にて、「SerialPort」を使え、というのが
サイトにあったのですが、
ツールボックスにSerialPortがありません。
追加する方法を教えてください。
使用環境:VS2008 C++ MFCアプリケーション
シリアル通信をするプログラムを作りたく、
VS2008にて、「SerialPort」を使え、というのが
サイトにあったのですが、
ツールボックスにSerialPortがありません。
追加する方法を教えてください。
使用環境:VS2008 C++ MFCアプリケーション
312デフォルトの名無しさん
2021/04/20(火) 20:36:15.98ID:mPkgRyxP ねぇねぇ今日は何処まで逝こうかな〜
COMはネイティブなのかね
COMはネイティブなのかね
313デフォルトの名無しさん
2021/04/23(金) 21:39:54.21ID:OsunfFOw >>311
SerialPortは使ったこと無いから知らんが、
その程度のことを自力で解決出来ない奴が今更VS2008でしかもMFCとか無理だ。
サイトを参考にするのもいいが、日付は必ず見るようにしろ。
.NET serial port で検索すると以下が当たるし、今なら普通にこれだと思うが。
https://docs.microsoft.com/ja-jp/dotnet/api/system.io.ports.serialport?view=dotnet-plat-ext-5.0
どうせ見えた展開だし、面倒だから先に言っておくが、
お前のやってることは初心者のあるある
・そもそもやり方を間違っているのに、それ以外の解決方法を認めない
・正しいやり方を教えても、それは聞いてないとして受け付けない
だ。だからどうせこれから文句も言うのだろうが、重ねて言うが、
今更その環境(VS2008+MFC)はあり得ないくらいの異常さだ。
お前が初心者で何も知らないだけなら、常に最新の環境を使うように心がけろ。それだけで無駄なことに嵌りにくくなる。
その環境に拘る何らかの理由があり、それを強いてきた上司等が居るのなら、まずそいつに聞け。
聞く人が居ないのなら、今のお前にその環境でやりきる能力はないから諦めろ。
SerialPortは使ったこと無いから知らんが、
その程度のことを自力で解決出来ない奴が今更VS2008でしかもMFCとか無理だ。
サイトを参考にするのもいいが、日付は必ず見るようにしろ。
.NET serial port で検索すると以下が当たるし、今なら普通にこれだと思うが。
https://docs.microsoft.com/ja-jp/dotnet/api/system.io.ports.serialport?view=dotnet-plat-ext-5.0
どうせ見えた展開だし、面倒だから先に言っておくが、
お前のやってることは初心者のあるある
・そもそもやり方を間違っているのに、それ以外の解決方法を認めない
・正しいやり方を教えても、それは聞いてないとして受け付けない
だ。だからどうせこれから文句も言うのだろうが、重ねて言うが、
今更その環境(VS2008+MFC)はあり得ないくらいの異常さだ。
お前が初心者で何も知らないだけなら、常に最新の環境を使うように心がけろ。それだけで無駄なことに嵌りにくくなる。
その環境に拘る何らかの理由があり、それを強いてきた上司等が居るのなら、まずそいつに聞け。
聞く人が居ないのなら、今のお前にその環境でやりきる能力はないから諦めろ。
314デフォルトの名無しさん
2022/02/16(水) 02:27:10.00ID:ky7QDxn6 記念カキコ
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 【中国外務省】日中関係悪化は高市氏に責任と名指しで非難… [BFU★]
- 【中国外務省】日中関係悪化は高市氏に責任と名指しで非難… ★2 [BFU★]
- 外務省局長は無言で厳しい表情…日中の高官協議終了か 高市首相“台湾”発言で中国が強硬対応 発言撤回求めたか…★2 [BFU★]
- 小野田紀美・経済安保担当相「何か気に入らないことがあればすぐに経済的威圧をする国への依存はリスク」 [Hitzeschleier★]
- 政府、株式の配当など金融所得を高齢者の医療保険料や窓口負担に反映する方針を固めた [バイト歴50年★]
- 【維新】吉村知事「中国人観光客だけに頼るビジネスモデル変えていかないといけない」「高市総理の発言は撤回する必要はない」 [Hitzeschleier★]
- 中国高官と話す外務省局長の表情、やばい [175344491]
- 中国外務省「日中関係の悪化は高市早苗首相が原因」と名指しで強く非難。キタ━(゚∀゚)━! [153490809]
- 小野田経済安保相「すぐに経済的威圧するところへの依存はリスク」😲 [861717324]
- 【高市速報】明日から中国からの輸入が停止すれば2ヵ月で国内の生産業に53兆円の損失発生 [931948549]
- 【悲報】ジャップ、どうやら中国が一方的に戦争仕掛けてくると思ってる模様😰 [616817505]
- 日本政府「高市総理の発言は問題ないと伝え、中国総領事のSNS投稿は問題があると中国に伝えました😊」 [931948549]
