X



Visual Studio 2008 Part 22
0001デフォルトの名無しさん垢版2014/10/13(月) 15:13:20.18ID:yFRqmPNp
■公式
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
0002デフォルトの名無しさん垢版2014/10/13(月) 15:18:37.82ID:Dm7iIvJX
               ノ      ゚.ノヽ  , /}      ...
            ,,イ`"     、-'   `;_' '    ..::::::::::::::...
   ,-、  _.._   (        (,(~ヽ'~     ..:::::::::::::::::::::::
 )'~  レー'  〉   ヽ       i`'}       .:::::::::::::::::::::::
 ~つ     '-ー、  i       | i'     ...:::::::::::::::::::::::
 /       <  /     。/   !  ......:::::::::::::::::::::::::    これは>>1乙じゃなくて
/         ~^´     /},-'' ,●::::::::::::::::::::::::::::::::::::
i、        ,i' _,,...,-‐-、/    i  ::::::::  .:::::::::::::
..ゝ        <,,-==、   ,,-,/      .:::::::::::            放射能がうんたら
 )       {~''~>`v-''`ー゙`'~       ..:::::::::                          ........::.
 {        レ_ノ            ..::::::::.                         ......:::::::::
ノ         ''           ..:::::::                        ...::.:...:::::::::
                     .:::::::::                     ...:......:::::::::::: .
                    .:::::::::::.        .....      ..  ..::::::::::::::::::::::::   :::.
                    ::::::::::::::::.::::::....:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::.. ::  ::..
                    .:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::    ::.
                    ::::::::::::::::: :::::::::::::::::::::::::::::: :::::
                          .::    ::.  :::
0003デフォルトの名無しさん垢版2014/10/14(火) 09:40:56.89ID:yI2xaj4J
>>1
0004デフォルトの名無しさん垢版2014/10/14(火) 09:42:38.35ID:yI2xaj4J
Visual Studio 2008 Express Edition の DVD イメージからのインストール
ttp://www.microsoft.com/japan/msdn/vstudio/express/maninstall/2008/default.aspx
・sp1適用済み
ttp://download.microsoft.com/download/6/F/1/6F161D1A-E893-4BFA-A53A-AF6B0D56A55D/VS2008ExpressWithSP1JPNX1504866.iso
・無印
ttp://download.microsoft.com/download/F/A/6/FA693F60-97D1-44EB-AC7F-6A44AC42B10E/VS2008ExpressJPNX1428694.iso

Microsoft Visual Studio 2008 Service Pack 1 (iso)
ttp://www.microsoft.com/downloads/details.aspx?FamilyId=27673C47-B3B5-4C67-BD99-84E525B5CE61&displaylang=ja
ttp://download.microsoft.com/download/b/0/4/b0482e09-09ca-4914-be2c-fd9b0d2bd1f3/VS2008SP1JPNX1512986.iso

ダウンロードの詳細 : MSDN Library for Visual Studio 2008 SP1:
ttp://www.microsoft.com/downloads/details.aspx?FamilyID=7bbe5eda-5062-4ebb-83c7-d3c5ff92a373&DisplayLang=ja

Microsoft Visual Studio International Pack 1.0 SR1
ttp://www.microsoft.com/downloads/details.aspx?FamilyID=44cac7f0-633b-477d-aed2-99aee642fc10&DisplayLang=ja
0005デフォルトの名無しさん垢版2014/10/14(火) 09:44:28.01ID:yI2xaj4J
Visual Studio Team System 2008 Test Agent 評価版
ttps://www.microsoft.com/japan/ordercenter/developer/vs2008testeval.aspx

Visual Studio 2008 Professional Edition 90日間 限定評価版
ttps://www.microsoft.com/japan/ordercenter/developer/vs2008proeval.aspx

Visual Studio Team System 2008 Team Suite, Visual Studio Team System 2008 Team Foundation Server, SQL Server 2005 評価キット
ttps://www.microsoft.com/japan/ordercenter/developer/vs2008tseval.aspx

Visual Studio Team System 2008 Team Suite (90 日間評価版)
ttp://www.microsoft.com/downloads/details.aspx?FamilyId=D95598D7-AA6E-4F24-82E3-81570C5384CB&displaylang=ja

Visual Studio Team System 2008 Team Suite リリース ノート
ttp://download.microsoft.com/download/1/a/c/1ace5b62-1fb8-4357-81f1-dbf92d805d9d/VS2008Readme.htm

Visual Studio Team System 2008 Team Foundation Server (90 日間評価版)
ttp://www.microsoft.com/downloads/details.aspx?FamilyId=B0155166-B0A3-436E-AC95-37D7E39A440C&displaylang=ja
ttp://download.microsoft.com/download/8/7/a/87a3ca58-91da-47b1-974e-a1f8529419e6/VS2008TeamFoundationServer90DayTrialJPNX1429245.iso
Visual Studio Team System 2008 Test Load Agent (90 日間評価版)
ttp://www.microsoft.com/downloads/details.aspx?FamilyId=572E1E71-AE6B-4F92-960D-544CABE62162&displaylang=ja

Visual Studio 2008 Professional Edition (90 日間評価版)
ttp://www.microsoft.com/downloads/details.aspx?FamilyId=83C3A1EC-ED72-4A79-8961-25635DB0192B&displaylang=ja
0006デフォルトの名無しさん垢版2014/10/14(火) 09:45:51.34ID:yI2xaj4J
Microsoft Visual Studio 2008 Service Pack 1 (インストーラ)
ttp://www.microsoft.com/downloads/details.aspx?familyid=FBEE1648-7106-44A7-9649-6D9F6D58056E&displaylang=ja

Visual Studio 2008 Shell (isolated mode) Service Pack 1 再頒布可能パッケージ
ttp://www.microsoft.com/downloads/details.aspx?FamilyID=021b3bee-b2ad-42a8-854a-c5eaef69e927&DisplayLang=ja

Microsoft Visual Studio 2008 Shell (isolated mode) 再頒布可能パッケージ
ttp://www.microsoft.com/downloads/details.aspx?familyid=ACA38719-F449-4937-9BAC-45A9F8A73822&displaylang=ja

Microsoft Visual Studio 2008 Express Edition SP1
ttp://www.microsoft.com/downloads/details.aspx?displaylang=ja&FamilyID=f3fbb04e-92c2-4701-b4ba-92e26e408569

Visual Studio 2008 Team Foundation Server Service Pack 1
ttp://www.microsoft.com/downloads/details.aspx?familyid=9E40A5B6-DA41-43A2-A06D-3CEE196BFE3D&displaylang=ja

ttp://download.microsoft.com/download/1/b/e/1be78474-c7f8-427a-8c6c-330e1c5db7d5/TFSReadmeSP1Final.htm

インテリセンス日本語対応
ttp://code.msdn.microsoft.com/KB957507
ttp://code.msdn.microsoft.com/KB957507/Release/ProjectReleases.aspx?ReleaseId=1854
0007デフォルトの名無しさん垢版2014/10/14(火) 09:47:09.34ID:yI2xaj4J
■過去スレ
ttp://pc11.2ch.net/test/read.cgi/tech/1174574352/ 【Orcas】 Visual Studio 2007 【.NET3.0】
ttp://pc11.2ch.net/test/read.cgi/tech/1187855872/ 【Orcas】 Visual Studio 2008 【.NET3.5】 Part2
ttp://pc11.2ch.net/test/read.cgi/tech/1193662588/ 【Orcas】 Visual Studio 2007 【.NET3.0】 Part3
ttp://pc11.2ch.net/test/read.cgi/tech/1195616628/ (実質4) Visual Studio 2008 Part1
ttp://pc11.2ch.net/test/read.cgi/tech/1198866447/ 【Orcas】 Visual Studio 2008 【.NET3.5】 Part5
ttp://pc11.2ch.net/test/read.cgi/tech/1202821357/ Visual Studio 2008 Part 6
ttp://pc11.2ch.net/test/read.cgi/tech/1204641201/ Visual Studio 2008 Part 7
ttp://pc11.2ch.net/test/read.cgi/tech/1207063618/ Visual Studio 2008 Part 8
ttp://pc11.2ch.net/test/read.cgi/tech/1210680571/ Visual Studio 2008 Part 9
ttp://pc11.2ch.net/test/read.cgi/tech/1217525513/ Visual Studio 2008 Part 11
ttp://pc11.2ch.net/test/read.cgi/tech/1221265969/ Visual Studio 2008 Part 12
ttp://pc11.2ch.net/test/read.cgi/tech/1226134233/ Visual Studio 2008 Part 13
ttp://pc11.2ch.net/test/read.cgi/tech/1230008197/ Visual Studio 2008 Part 14
ttp://pc12.2ch.net/test/read.cgi/tech/1233853864/ Visual Studio 2008 Part 15
ttp://pc12.2ch.net/test/read.cgi/tech/1238941772/ Visual Studio 2008 Part 16
ttp://pc12.2ch.net/test/read.cgi/tech/1245309571/ Visual Studio 2008 Part 17
ttp://pc12.2ch.net/test/read.cgi/tech/1251622158/ Visual Studio 2008 Part 18
ttp://pc12.2ch.net/test/read.cgi/tech/1259076828/ Visual Studio 2008 Part 19
ttp://hibari.2ch.net/test/read.cgi/tech/1269602041/ Visual Studio 2008 Part 20
ttp://peace.2ch.net/test/read.cgi/tech/1290969016/ Visual Studio 2008 Part 21
0009デフォルトの名無しさん垢版2014/10/20(月) 09:48:36.53ID:eWr20XAi
WindowsのExplorerで「やり直し」と「元に戻す」の機能がありますが
その具体的な内容が判らないので「何をやり直すのか」「何が元に戻るのか」が判りません
XPのときはSP3あたりから編集メニュー上にマウスカーソルを持っていくとステータスバーに内容が表示されていました
Windows7も編集メニューの方ではなくファイル一覧の何もないところで右クリックでコンテキストメニューを出すと
「やり直し」と「元に戻す」があってそこにカーソルを持っていくとステータスバーに出て来るようになりました
Windows8になるとまたエクスプローラーが先祖返りしてステータスバーに何も表示されません
なんでこんな糞設計のまま放置プレイなんでしょうか?
0014デフォルトの名無しさん垢版2014/11/08(土) 16:20:15.32ID:qwvGzBPO
CH3COOH
0017デフォルトの名無しさん垢版2014/12/12(金) 12:20:12.75ID:r3Fvlg1D
結局、MS Office は .NET では書かれないんだからな。そりゃCOMとOLEが残るわな。
0018デフォルトの名無しさん垢版2015/01/29(木) 11:54:57.76ID:/eP3JLu1
cprintf("5パーセントの税金表を表示します\n\r");
なぜだか、文字化けしてしまいます
どうしてですか?
0019デフォルトの名無しさん垢版2015/01/29(木) 13:18:53.41ID:4vB8OE29
Visual C++ 2005以降では、cprintf(POSIX関数)は使用しないでください。代わりにISO C++準拠の_cprintfまたはセキュリティが強化された_cprintf_sを使用してください。
0025デフォルトの名無しさん垢版2015/02/02(月) 10:39:22.67ID:Tt8Kn9ql
コマンドとして実行したときは、同じ結果になるけど
行数をカウントするソフトなどでバイナリ比較したとき、不具合になる可能性がある
0030デフォルトの名無しさん垢版2015/02/04(水) 09:28:42.40ID:fF80T871
\r\n と書くと \x0D\x0D\x0A を出力する変な環境があったな
(コンパイルオプションとか fopen の wb|ab とか付け忘れじゃなくて)
0031デフォルトの名無しさん垢版2015/02/05(木) 00:08:21.94ID:l8QaN41D
Windowsだな。
\n は、C言語とかでは単に「改行」を表すエスケープシーケンスであって、
実コードは環境によって変わってくる。
Windowsでは 0x0D, 0x0A、Unixは0x0A、昔のMacは0x0Dだったとか。
0032デフォルトの名無しさん垢版2015/02/05(木) 08:29:11.69ID:n7T33kxd
知らないならレスしないでください
うざいだけです
003431垢版2015/02/05(木) 23:37:48.31ID:7AipLZm5
俺のことか?
\nが0x0D,0x0Aなんだから、0x0Dになる\rに繋げて \r\n とすれば、
0x0D,0x0D,0x0Aが出力されるのは当然だろ?
0035デフォルトの名無しさん垢版2015/02/06(金) 06:10:49.98ID:FVCocBTO
いや、Windowsだろうがなんだろうが「0x0d=\r」「0x0a=\n」だよ
これは変わらない
OSによって「\r」「\n」「\r\n」のどれかをシステム標準としているだけ
のこと
0037デフォルトの名無しさん垢版2015/02/06(金) 11:52:15.65ID:0UnHsvEY
>>35
Windows2000のtracertとか
\n\r なんてやってるコンソールアプリがあるわけだが・・・

>tracert 2ch.net>log.txt
0038デフォルトの名無しさん垢版2015/02/06(金) 12:31:07.66ID:XYA8veRx
>>37
unix系譜のコマンドを持ち出してくるってことは、分かった上でやってるんだと思うが
やらしいなキミは
システム標準の意味をもうちょい考えようね
0040デフォルトの名無しさん垢版2015/02/07(土) 01:10:14.98ID:1rQMkrzn
いやいや、なんのこっちゃ

>r\n と書くと \x0D\x0D\x0A を出力する

「出力する」

だろ?
そりゃ確かに\n自体は0x0Aだし\rは0x0Dだが、「出力する」という事に対しては
Windowsは\nが0x0D,0x0Aじゃないか。
0043デフォルトの名無しさん垢版2015/02/07(土) 16:49:52.23ID:Hof4fFat
すれち
0044デフォルトの名無しさん垢版2015/02/07(土) 17:51:19.90ID:TiU3gCM4
テキストモードでのファイル出力を使うと
Windowsでは \n が \r\n(0D,0A) に変換される だろ
0046デフォルトの名無しさん垢版2015/02/08(日) 13:36:14.40ID:kikHBD4l
大元が>>30 で、wbつけ忘れじゃないと書いてるんだからバイナリーモードの話のはずなのに
テキストモードの話を始めるからだよ
0047デフォルトの名無しさん垢版2015/02/09(月) 08:19:19.65ID:hAsZKmdY
>>46
だとしてもそれどんな環境よ?ってのは疑問が残るな
Windowsだから、ではないのは明白

で、出力するときに変換したらなんていいだしたらそりゃなんであろうがしたらそーなるだろってのは
そんな的外れでもないと思う
0048デフォルトの名無しさん垢版2015/02/21(土) 21:55:00.33ID:plzH3cvn
http://downloads.ddigest.com/software/download.php?sid=1051&;ssid=0&did=3
ここからダウンロードしたVOBSUB2.23のソースですが、すぐにコンパイルできるものなのですか? Microsoft SDKsのサンプルを揃えたとしても文法えらーばかり出るのですが。
例えばこんな感じ。

for(int i=0; i>3; i++)
{
〜〜〜
}

for(i=0; i>3; i++) <-- ここでえらー
{
〜〜〜
}

あと、きちんとキャストしていなかったりと・・・かなり甘めのオプションとかつけてコンパイルしているのかなあと。
0050デフォルトの名無しさん垢版2015/02/22(日) 07:45:29.13ID:uX3Bvmht
さすがにそれは判ってて質問してるだろ

いちいち甘めのオプションで〜って話だと受け止めたが
0051デフォルトの名無しさん垢版2015/02/22(日) 10:05:49.59ID:+Mmh1x19
>>48
昔のCやC++とブロックのスコープが変わってるからな。
とくにfor文の int は昔と今で扱いが違う。
0052デフォルトの名無しさん垢版2015/02/22(日) 10:28:09.76ID:tFIS8X7o
レスありがとうございます。
一応分かってるつもりで質問したのですが
元のソースがVC6からVC7へ変換してある形跡があって
そのslnソリューションをVS2008で私がさらに変換した状態です。
先ほどのエラーはほんの一例でよくコンパイラがとおったなと思う
レベルでびっくりしました。プログラムは複雑なのに。
後はキャスト変換がおかしいとか、そういうのばかりだったので
地道に文法エラーだけはつぶしました。
今のところ、見た目はきちんと動いているように見えます。
VC7を使っているとすれば先ほどのコンパイルエラーくらいは
出るだろうと思っていたのですが、作者はどうしていたのでしょうね。
0057デフォルトの名無しさん垢版2015/07/15(水) 13:26:02.23ID:mBlD3Q7e
VC++6.0で作ったActiveXコントロールを64bit化したいと思い
Visual Studio 2008でプロジェクトを開きコンパイル
してみたのですが

error RC2135 : file not found: hoge.tlb

というエラーがどうしても治せません。
なにかヒントになるようなものはないでしょうか?
よろしくお願いいたします。
0059デフォルトの名無しさん垢版2015/09/23(水) 15:19:11.68ID:mtvdh8Dc
ちょっとあげておきます
0060デフォルトの名無しさん垢版2015/09/30(水) 17:09:43.49ID:wkKKGVGV
Visual Studio 2008(Basic, C#, C++)の
 ヘルプ → 製品の登録
からライセンス登録の手続きをして登録キーを手に入れたいのですが
どうすればいいのでしょうか?
どなたか心優しい方、どうか教えてくださいませ。
私のパソコンOSはWindows Vista Businessです。
0061デフォルトの名無しさん垢版2015/09/30(水) 19:13:52.56ID:AXFtzTRL
あきらめろ
006260垢版2015/09/30(水) 20:56:54.91ID:wkKKGVGV
>>61
そこをなんとかお願いします。

…もしかして「あきらめろ」というのは「それは不可能」という意味ですか?
0063デフォルトの名無しさん垢版2015/10/01(木) 08:18:22.09ID:mpdw7HPU
悪魔の囁きに載るな
006460垢版2015/10/01(木) 08:30:19.07ID:5sGFr3sa
どなたか教えてください。30日以内に登録しなきゃ駄目らしいんで。

https://msdn.microsoft.com/ja-jp/library/ms246592(v=vs.90).aspxで登録方法を調べました。
「3.Passport にサインインし、オンライン登録フォームに入力します。」と書いてあります。
しかし、Passportへのサインインのしかたが分かりません。
そもそもPassportってなんなのかも知りません。
ど素人でまことに申し訳ないんですが、どなたかよろしくお願いします。
006660垢版2015/10/02(金) 19:16:01.01ID:AWZIs7jF
>>65
その「マイクロソフトのアカウント」の取得方法を教えていただけないでしょうか
無知など素人で誠に申し訳ありません
006960垢版2015/10/05(月) 19:08:49.27ID:dhDe7Zf7
>>67, >>68
すみません
そのウェブサイトに行っても、どこにも「登録キー」を取得するページが見つかりません
本当にすみませんが、URLだけでなく具体的にどうしたらいいかを教えてください
よろしくお願いします
0070デフォルトの名無しさん垢版2015/10/05(月) 20:17:42.89ID:8plgvxHj
まずMicrosoftアカウントを取得

そのMicrosoftアカウントでログイン(旧Passport)

2008登録...ってまだできるの?
0071デフォルトの名無しさん垢版2015/11/01(日) 17:46:18.91ID:wW4dECTr
2008ってWindows10で動く?
0072デフォルトの名無しさん垢版2015/11/06(金) 17:15:53.66ID:bip5Bf06
Visual Basic 2008 Express
GF834-7Q2DB-FG2WR-987CY-CV4GY

Visual C# 2008 Express
FBT3W-MHQHF-PTDCF-66Y32-BQ9XM

Visual Web Developer 2008 Express
JYRQW-R4M7G-6HHX8-T2C3Y-KCG9M

VS2008ExpressWithSP1JPNX1504866.isoの vs_setup.MS_ の中にあったキー
0073デフォルトの名無しさん垢版2015/11/13(金) 05:38:02.63ID:/OfqoLLw
>>70
Win10に入れてるけど、通知をクリックしても登録は出来ない
iso持ってるなら通知は止まらんがそのまま使用可能
0074デフォルトの名無しさん垢版2015/12/14(月) 21:44:25.18ID:FHkK4gA8
VS2008自体ってDPIスケーリングに対応してなくない?
しかもdevenv.exeを右クリックしても「互換性」のタブすら出てこなくない?
0077デフォルトの名無しさん垢版2015/12/18(金) 22:34:12.78ID:fM7+Vhbq
DPI設定を変えているPCでVS2008を使うとダイアログなどの文字がボヤけて見にくいのが困ります。
0079デフォルトの名無しさん垢版2015/12/19(土) 23:20:20.16ID:t2VnwwG/
1行目はただの感想ですね。
2行目も今より解像度高いモニタ使ってどうするんですかw
0080デフォルトの名無しさん垢版2015/12/22(火) 17:00:55.68ID:84O49K/C
Windows10にVS2008入れて動かした人いる?

実際入れてC++コードのx64のプロジェクトをデバッグでステップ実行させようとしたら
ローカルデバッグにしているはずなのに何故かリモートで動こうとして全く駄目だわ。

x86のプロジェクトだと普通に動いて草w
もちろん64bitOS環境なんだが、なんかまずいことでもあるんかねー
0083デフォルトの名無しさん垢版2016/01/27(水) 07:59:16.52ID:zSpoUlJp
ランタイムライブラリ→マルチスレッド(/MT)に設定してるんだけど、
外部のライブラリを、追加の依存ファイルで設定して、
リンクするときに静的にEXEに埋め込めると思ったのですが出来ないんだっけ?
他に設定とかあります?
0084デフォルトの名無しさん垢版2016/01/27(水) 12:42:35.88ID:sapMCej1
/MT関係なく、外部のライブラリは普通にスタティックにリンクされるでしょ
それがダイナミックリンクライブラリなら、その時も/MT関係なくDLL使用になるし
0085デフォルトの名無しさん垢版2016/01/27(水) 19:57:56.71ID:L48s/ty/
>>84
DLLはEXEの中に組み込まれないの?
他の環境で動かそうとしたら、「〜DLLが見つからない」ってエラー出たから。
0086デフォルトの名無しさん垢版2016/01/28(木) 11:26:11.51ID:Zt+/Dst2
それは無理
スタティックリンクライブラリとダイナミックリンクライブラリは別物なので
LIB作成時に両方作るか、どちらかに決めておかないと。
0087デフォルトの名無しさん垢版2016/01/28(木) 12:44:14.37ID:QZ7ojH/n
>>86
ありがとうございます。

DLLが見つからなかった場合、ライブラリを使う関数を使わないようにする
宣言か何かあったと思ったけど、方法わかりますでしょうか?
ググる際のキーワードでもいいですので教えていただけますと助かります。
0088デフォルトの名無しさん垢版2016/01/28(木) 14:10:53.25ID:Zt+/Dst2
どうだろ、、
SearchPath で事前に探しても探さなくてもいいけど
LoadLibrary の戻りで判定しては。
見つかった場合はGetProcAddress使って呼び出せる。
0094デフォルトの名無しさん垢版2016/03/15(火) 15:00:08.48ID:ZBek540b
何が大勝利なんだろ?
頭おかしいのかな?
0111Office & Gamers @ 試験運用中(トリなしw垢版2016/08/29(月) 03:30:44.79ID:UdG9pR1y
スレ建て規制により、DarkGDK次スレが建つまでこちらへw

[ お手軽3Dゲーム開発♪ ] DarkGDK Part.2
http://hayabusa6.2ch.net/test/read.cgi/pc2nanmin/1452964616/

[ お手軽2Dゲーム開発♪ ] 99BASIC Part.1
http://hayabusa6.2ch.net/test/read.cgi/pc2nanmin/1462503999/

[ MML / MIDI ] ゲーム開発用サウンド、BGMスレ
http://hayabusa6.2ch.net/test/read.cgi/pc2nanmin/1453832565/

MenuetOS 64bit版 アセンブリ言語 プログラミング
http://echo.2ch.net/test/read.cgi/tech/1460581443/

[EXEファイル可] JavaScript統合開発環境 DX Studio
http://echo.2ch.net/test/read.cgi/tech/1423340731/

VC++ with DarkGDK and multi thread programming
http://jbbs.shitaraba.net/bbs/read.cgi/computer/44261/1466446558/l100
0114デフォルトの名無しさん垢版2016/10/25(火) 06:47:31.51ID:z9wtE8t2
光学メディアに焼いてインストールすれば
Micorsoftに登録しなくても使えるって利点があるよね。

ネットワークから隔離した古い機械・古いOSで使える。
0120デフォルトの名無しさん垢版2017/02/16(木) 22:00:42.08ID:7GOAgwDK
Panda3D SDK 1.9.3をMicrosoft Visual C++ 2008 Express Edition
で使いたいのですが、インクルードで躓いてます。

どうやるのか教えてください
0121片山博文MZ ◆T6xkBnTXz7B0 垢版2017/02/16(木) 22:42:51.55ID:soSRPnhw
>>120
汚い方法は、インクルードパスに必要なヘッダーファイルを貼り付けて、ライブラリパスにビルド済みのライブラリファイルを貼り付ける。
システムを汚さない方法はプロジェクトのプロパティでヘッダーファイルがある場所をインクルードパスに追加し、ビルド済みのライブラリファイルがある場所をライブラリパスに追加。
これでOK。
0124デフォルトの名無しさん垢版2017/02/16(木) 22:59:24.65ID:lXiZQpBh
print "
とすると勝手に
print ""になってエンターを押すと
print "
"
っておかしくなります
print ""
|
ってするにはどおするばよいですか?
うまく伝えてられるかわかりませんがよろしくお願いします
m(_ _)m
0126デフォルトの名無しさん垢版2017/02/17(金) 00:25:38.74ID:NkX+r5wc
回答

ありがとう
0128デフォルトの名無しさん垢版2017/05/18(木) 08:51:36.17ID:thYMhZbz
>>60
コメント内容
試用期間
EEは無料
0129デフォルトの名無しさん垢版2017/05/18(木) 08:52:36.67ID:thYMhZbz
>>60
eメールのアカウントが必要
0130デフォルトの名無しさん垢版2017/05/18(木) 09:02:35.23ID:thYMhZbz
dll
0131デフォルトの名無しさん垢版2017/05/18(木) 09:03:37.43ID:thYMhZbz
>>124
コメント内容
パソコンの周りをきれい委にする。
0132デフォルトの名無しさん垢版2017/05/18(木) 09:04:21.32ID:thYMhZbz
今の時代、パソコンでテレビが見れないとだめなのか。
0133デフォルトの名無しさん垢版2017/05/18(木) 09:12:17.83ID:thYMhZbz
.iso
0134デフォルトの名無しさん垢版2017/06/03(土) 19:22:27.66ID:cZuYHM9v
古い奴だとお思いでしょうが、古い奴こそ新しいものを欲しがるもんでございます。
どこに新しいものがございましょう…
「傷だらけの人生」
藤田まさと作詞・吉田正作曲
0135デフォルトの名無しさん垢版2017/06/15(木) 00:13:00.81ID:0Bo/JfNC
KB957507って現在は入手不可能?
0138デフォルトの名無しさん垢版2018/01/20(土) 12:54:23.17ID:bSTKludV
VC++2008にユーザプリプロセッサを噛ませる方法ってある?

関連質問は以下。
http://mevius.2ch.net/test/read.cgi/tech/1514025223/395
VC++2017相当のラムダをVC++2008で使いたい。
MSVCのプリプロセッサだけでは多分無理っぽい。
自前のプリプロセッサをまず通し、結果をVSでコンパイルすれば確実にいけるのだが、
これをやる方法ってある?
(自前のプリプロセッサはスクリプト言語で書く)
0139デフォルトの名無しさん垢版2018/01/20(土) 13:28:02.32ID:5zEZap2N
.cppじゃなくて.cupみたいなソース書いて
.cup->.cppにするならいける
0141デフォルトの名無しさん垢版2018/01/20(土) 13:44:14.42ID:5zEZap2N
最近の人はmake書いたこと無いんか
0143デフォルトの名無しさん垢版2018/01/20(土) 14:25:54.52ID:Hc/lJP5p
Makefile家や
0144デフォルトの名無しさん垢版2018/01/20(土) 14:27:12.33ID:4AOaXNlF
make書いたら負け
0145デフォルトの名無しさん垢版2018/01/20(土) 14:40:08.73ID:bSTKludV
まあどっちでもいいと思うが。

Cマクロで出来れば一番簡単だが、どうやらこれは無理。
ならば次善策は自前でのスクリプティングであり、
主な手間はmakefile/カスタムビルドツール設定ではなく、
スクリプトを作成することなんだから、この際起動はどっちでもいいだろ。
0146デフォルトの名無しさん垢版2018/01/20(土) 15:02:15.30ID:4AOaXNlF
Dで書いてobjリンクする
0147デフォルトの名無しさん垢版2018/01/20(土) 15:57:47.74ID:bSTKludV
ちなみに、以下確かに動くのだが、これってどうなん?
https://stackoverflow.com/questions/472667/lambda-expressions-support-in-vs2008-sp1
(超絶簡単なソースしか試してないが)

・コンパイルは c:\windows\microsoft.net\framework\v2.0.50727\system.dll : warning C4945: が出つつも通る。
・F5でのデバッグ実行が出来ない。「デバッガのプロトコルがデバッグされる対象と互換性がありません」
・IntellisenseはVC++/CLIでも機能している。


>>146
なおラムダはGUIからの機能選択部で使うので、
結構な頻度で追加/書き換えしており、ソースは分離したくない。
普通に考えればVC++2017に上げればいいだけではあるが、
環境を変更すると色々他の問題が発生するかもしれないのでちょっと無理しようとしている。
0149デフォルトの名無しさん垢版2018/01/20(土) 16:09:16.48ID:5zEZap2N
>>147
>確かに動くのだが、これってどうなん?

動くならそれでいいんじゃない?

同じレス内で

>環境を変更すると色々他の問題が発生するかもしれないので

っていうのとは真逆の態度だとは思うが
0150デフォルトの名無しさん垢版2018/01/20(土) 23:47:48.29ID:bSTKludV
まだカスタムビルドには組み込んでいないが、スクリプトを作成し、動作することを確認した。
知恵を絞ってくれた人はありがとう。現在の解決策は以下。

・#define LAMBDA でインラインの展開を行う。
・クラス宣言部はスクリプトで作成し、これをincludeする。

VS2017に上げてもLAMBDAマクロ宣言部だけの変更(1行)で済む予定なので、まあまあかと。
とりあえずこれで様子見します。
0151デフォルトの名無しさん垢版2018/04/10(火) 07:51:46.77ID:25Me0atb
最終列車に乗り遅れるな

VC++2008Expressサポート切れまであと1日。
2018年4月11日(水)でサポート終了。

修正パッチの入手の終わってない人は忘れないように。
0152デフォルトの名無しさん垢版2018/04/10(火) 14:36:15.41ID:JIHFaEMv
GJ
0153デフォルトの名無しさん垢版2018/04/11(水) 01:33:09.61ID:PizNPnSY
必死だなぁw
0155デフォルトの名無しさん垢版2018/04/11(水) 13:06:06.48ID:bG1z7LTF
ああ終わったか
乙でした
0156デフォルトの名無しさん垢版2018/04/11(水) 13:26:11.45ID:bG1z7LTF
てst
0157デフォルトの名無しさん垢版2018/04/12(木) 14:51:25.15ID:nqXIWDjI
《 後継開発環境のご案内 》

LinuxMintのダウンロードはこちらから。

Main Page - Linux Mint
https://linuxmint.com/
https://linuxmint.com/download.php
---------

AGK無料試用版の配布開始(リンク先にWindows、Mac、Linux版のファイルが直接置いてある)

AppGameKit - Free Trial Version
https://www.appgamekit.com/trial

無料試用版

AppGameKit無料トライアル版は、AppGameKitの主要な領域すべてにアクセスできるため、
完全に評価することができます。完全版の有料版には、次の主要機能が含まれています。

・ Android、iOS、HTML5にプロジェクトをエクスポートする
・ アプリをデバイスに直接ブロードキャストする
・ コンパイルされたプロジェクトからウォーターマークを削除する
0158デフォルトの名無しさん垢版2018/04/16(月) 00:56:57.36ID:CadfvnK3
WineでPassmarkとHDbenchを試したところ、シングルスレッド性能はWindowsより若干高く、マルチコア性能は半分程度に留まった。
おそらくWine内部処理の都合と言うことにw

また、DirectXテストは通らなかった。GDIクラスのみ。
0159デフォルトの名無しさん垢版2018/04/22(日) 03:49:49.80ID:CAx4oxnE
…って言う訳で、早速Linuxのパフォーマンステスト。

64x64ピクセルの2Dスプライトの表示枚数をカウントして、パフォーマンスを計測してみよう。
ダウンロードは以下のリンクからどうぞ。
http://upload.saloon.jp/src/up27011.zip

Firefoxブラウザの右上にダウンロードマーク(↓)の付いたアイコンをクリックして、ファイル
アイコンをクリックすると、zipファイルの入ったフォルダが表示されるので、右クリックして
「 Extract Here 」 を選ぶ。

次に、「 agk_sample 」 と言うフォルダが作成されるので、ダブルクリックする。

フォルダの中に 「 abc 」 と言う拡張子のないファイル、「 media 」 と言うランタイムの入った
フォルダが作成されている。

「 abc 」 と言う拡張子のないファイルが、実行ファイルで、これを迷わずダブルクリックすれ
ばよいw

だいたい2分ぐらいで最大表示枚数が安定する。
プログラムの終了は [ ESC ] キー。

Celeron G1820 + Intel HD無印 で1500枚程度。
0160デフォルトの名無しさん垢版2018/05/23(水) 19:42:34.90ID:Au5e7VGg
僕の知り合いの知り合いができたパソコン一台でお金持ちになれるやり方
役に立つかもしれません
グーグルで検索するといいかも『ネットで稼ぐ方法 モニアレフヌノ』

CRP7I
0162デフォルトの名無しさん垢版2018/05/25(金) 19:20:37.97ID:TsdeULHr
ではではw

Intel Pentium G5 CoffeeLake 総合スレ
http://anago.open 2ch.net/test/read.cgi/jisaku/1526884213/
0163デフォルトの名無しさん垢版2018/07/04(水) 22:48:21.01ID:gFgZc5FG
TJH
0166デフォルトの名無しさん垢版2018/09/13(木) 23:46:46.29ID:MPXnmy/B
起動の仕方で浮動小数点演算に誤差が発生するのだけど、理由が分かる人居ますか?

今のところ、

A. Debugビルドのバイナリをダブルクリックして起動
B. Releaseビルドのバイナリをダブルクリックで起動
C. DebugビルドまたはReleaseビルドでF5で起動

の3種類出来てる。それぞれ微妙な誤差だ。(doubleの下位ビット)
AとBの違いについては諦めていたのだが、(なお両方とも/fp:precise)
実はCもあると気づいてしまった。

なお、バイナリをダブルクリックして起動、それにIDEをアタッチしても結果は変わらない。
それぞれAまたはCが出る。

何かIDEの設定を間違っているのだと思うのだけど…
0167デフォルトの名無しさん垢版2018/09/14(金) 12:43:29.26ID:5xDSXwp0
0fillしてないんだろ
0168デフォルトの名無しさん垢版2018/09/14(金) 13:05:12.93ID:XcO59d50
再現性は100%なので、初期化のミスではない。(と思っている)

演算途中の結果を double なら16進16桁でテキストにダンプしている。
数値だけではないが500MB程度のファイルが出力され、
diff を取ることによりレグレッションテストをしている。
今のところ、A/B/Cの3種類しか出ない。
初期化忘れならこうはならない。(はず)
0169デフォルトの名無しさん垢版2018/09/14(金) 13:09:49.07ID:Qw2nkUqU
MSのエンジニアを信じるか、再現可能なソースも示さず問題だ問題だ言ってるとこの馬の骨とも知れない奴を
信じるかって言われたら迷うことなく前者を信じるw
0170デフォルトの名無しさん垢版2018/09/14(金) 14:43:10.29ID:XcO59d50
俺はIDEのバグだとは思っていない。
何かIDEの設定があって、俺がそれを適切にやってないのだと思っている。

色々見た限り、俺は /fp:precise しか発見出来なかった。
ただしこれは一応適切に設定されている。
他にないかな?ということ。
0171デフォルトの名無しさん垢版2018/09/14(金) 15:49:43.21ID:cyu8WCuc
IDEじゃなくてコマンドラインからコンパイラで直接コンパイルしても一緒?
0172デフォルトの名無しさん垢版2018/09/14(金) 16:14:47.18ID:XcO59d50
どういう意味?
(どれとどれの違いにフォーカスしろと?)

俺はバイナリに問題があるとは思っていない。
何らかの理由で浮動小数点のモードが切り替えられたりしてないかを疑ってる。
だからIDEの設定とか、そっちを見てる。

Release/Debugのバイナリは当たり前だが違ってる。
/O2と/Od等だ。
ただそれでも /fp:precise の場合は
浮動小数点の演算順序を入れ替えない範囲で最適化される事になっている。
逆アセンブラは見たけどちょっとグチャグチャすぎてよく分からなかった。
(見た範囲では演算順序の入れ替えはないように思えた)
0173デフォルトの名無しさん垢版2018/09/14(金) 16:25:44.73ID:2giHKuhd
>>166
double型を使っていても、SSEのXMMレジスタなどを使う場合、昔のfld, fst, fmulなどを使う場合より基本的には精度が落ちる。

丸めの方向も四捨五入、正負どちらかの方向への丸めや切り捨てなどの他、確か、精度を気にしない、なんてオプションもあった気がする。ゲームで使うことを想定しているらしい。

SSE用に最適化を掛けると、速度は上がるが精度は落ちるかも知れない。
0174デフォルトの名無しさん垢版2018/09/14(金) 17:45:18.51ID:XcO59d50
>>173
今の範囲ではSSEは使っていない(はず)
「拡張命令セットを有効にする」は「設定無し」になっている。(多分デフォのまま)
見た目全部x87が出てたし。

やっぱRelease/Debugの違いから攻めろって感じか?
俺もF5起動で結果が異なるってのは全く予想してなかったし。(ただしこちらの問題だろうけど)
演算部分は場合によってはSSEのアセンブラに差し替えるので、
問題になる場合には、Release/Debugの違いはこれで吸収するつもりだった。
(これは1ヶ月後にやるかも)
0176デフォルトの名無しさん垢版2018/09/14(金) 21:39:03.40ID:fXySkelb
再現するコードをみないとなにもわかるわけがない
低学歴知恵遅れが書くコードなんかなにをやってるか分からないからな

ごちゃごちゃいってないで再現するコードをあげなさい
0177デフォルトの名無しさん垢版2018/09/15(土) 06:26:55.94ID:/OsufeBT
月並みな意見だけど、
「症状を再現できる最小のソースと初期データ、それとコンパイル環境」
まで切り詰めてみるのが早道じゃないかな。

ちょくちょく発生する事例なら、解決策を知ってる誰かが教えてくれてるかと。
週末、より多くの人が質問を見ることを期待して待つ手もあるけど。
0178デフォルトの名無しさん垢版2018/09/15(土) 08:56:57.28ID:9ZmI9OgI
より基本に立ち返ろう
そもそも誤差はあるのか?

計算結果を何を使ってどう出力しているかだけでもソースを見せてくれ
0179デフォルトの名無しさん垢版2018/09/15(土) 13:36:34.65ID:heijdb7v
>>174
x87でも誤差を丸める方法を fpu control word で設定できる事は出来る。
四捨五入と切り捨てなどを切り替えられる。
0180デフォルトの名無しさん垢版2018/09/15(土) 13:42:47.95ID:heijdb7v
fpu control word で、丸め方法と、精度の二つを独立に設定できる。

この精度の設定で、メモリ上の表現がdouble型でも、計算時のfpuの内部精度が変わってくる。

普通は64bit doubleに対して、fpu内部では80bitの精度で計算する。仮数部のbit数は、確か、それぞれ、53BIT、64BITだったかな。
0181デフォルトの名無しさん垢版2018/09/15(土) 14:05:09.61ID:heijdb7v
Intel® 64 and IA-32 Architectures Software Developer’s Manual

[Vol 1]

11.6.8 Compatibility of SIMD and x87 FPU Floating-Point Data Types

SSE and SSE2 extensions operate on the same single-precision and double-precision floating-point data types that
the x87 FPU operates on. However, when operating on these data types, the SSE and SSE2 extensions operate on
them in their native format (single-precision or double-precision), in contrast to the x87 FPU which extends them
to double extended-precision floating-point format to perform computations and then rounds the result back to a
single-precision or double-precision format before writing results to memory. Because the x87 FPU operates on a
higher precision format and then rounds the result to a lower precision format, it may return a slightly different
result when performing the same operation on the same single-precision or double-precision floating-point values
than is returned by the SSE and SSE2 extensions. The difference occurs only in the least-significant bits of the
significand.
0182デフォルトの名無しさん垢版2018/09/15(土) 14:14:58.92ID:heijdb7v
>>181
書いてある意味は、

「SSEやSSE2だと、float(32BIT)やdouble(64BIT)のまま計算するが、x87 fpuだと、もっと高い精度であるところの
  『double extended-precision floating-point format(拡張倍精度浮動小数点フォーマット:80BIT)』
で計算を実行して、丸めてから、floatやdoubleに戻す。
そのため、SSE/SSE2 と x87 fpuでは結果が変わることがある。
しかし、その場合でも結果の違いは、仮数部の LSB (最も価値の小さいBIT)の1BITにだけ現れる。」

というような事。
0183デフォルトの名無しさん垢版2018/09/15(土) 16:09:28.75ID:aC3C7hdp
揚げ足取りだけどLSBを「最も価値が小さい」って直訳はいかがなものかなw
普通に最下位ビットじゃないの?

ところで
> the least-significant bits
これ何で複数形なのかね
0184デフォルトの名無しさん垢版2018/09/15(土) 16:14:15.89ID:AVfR6YnT
2の0乗だから実際価値が低い

上はMVBで
0185デフォルトの名無しさん垢版2018/09/15(土) 17:07:56.98ID:UR1d6CKz
>>182
ありがとう。
ただ一応それは知ってて、その上で、IDEの環境設定等を疑っている。

>>177
とはいえ地道に辿って、同様の再現コードを作ることに成功しそうだ。
もう少し調べて、多分今晩か明日午前中に上げる。
0186デフォルトの名無しさん垢版2018/09/15(土) 17:12:32.47ID:heijdb7v
>>183
「The difference occurs only in the least-significant bits of the significand.」

これは、SSE の場合の LSB と、x87 FPU の場合の FPU の2種類を頭の中に想定していると思われる。

SSE: a1 = 1.xxxxxxxxz * 10^b
x87 : a2 = 1.yyyyyyyyw * 10^c

つまり、LSB は、↑のように、z と w で、2つあるので、LSBs という英語になる。
0187デフォルトの名無しさん垢版2018/09/15(土) 17:15:04.14ID:heijdb7v
誤:これは、SSE の場合の LSB と、x87 FPU の場合の FPU の2種類を
正:これは、SSE の場合の LSB と、x87 FPU の場合の 2種類を
0188デフォルトの名無しさん垢版2018/09/15(土) 17:18:55.19ID:heijdb7v
>>183
>揚げ足取りだけどLSBを「最も価値が小さい」って直訳はいかがなものかなw
>普通に最下位ビットじゃないの?

整数の場合は、「最下位ビット」というと、本当にBITの位置が一番右にあるようなイメージもある。

一方、浮動小数点数の場合は、右にあるとかより、仮数部において、一番価値の小さいビット、というニュアンスを使えたかった。

IEEEでは、それは確かに一番右にあるビットであって、マシン語レベルの表現では、BIT0ではあるのだが。

ニュアンス的に。
0190デフォルトの名無しさん垢版2018/09/15(土) 20:35:40.44ID:UR1d6CKz
同様の症状を再現出来るようになったので上げる。
完全再現は出来てないが、使い物にはなるはず。興味がある人はよろしく。

症状:
単独で起動した場合と、IDEから起動した場合で、結果が異なる。

環境:
VS++2008ExpressEdition

再現方法:
1. 新規プロジェクトを作成。(CLRコンソールアプリケーション。オプション等は全てデフォのまま)
2. mainを以下ソースと差し替える。
3. Releaseビルドで実行する。(Debugビルドでは再現しなかったので注意)

結果:
0.000000, 0x1ff68ddfb62221dd (IDEからの起動(F5))
0.000000, 0x1ff68ddfb62221de (コマンドプロンプトからの起動)
最後の2bitが異なる。(誤差は1bit)

備考:
俺が遭遇しているのとはやや異なる。(俺の場合、Debugビルドでもこれが発生する)
この再現状況だと、単に
「DebugとReleaseでバイナリが異なり、
IDEから起動した場合は常にDebugバイナリを掴んでいるだけでは?」
とも取れるが、こちらで確認した限りはちゃんとReleaseバイナリを掴んでいる。
理由は、
1. Debug/Releaseの両方のバイナリがない状態で実行した場合、
 自動的に作成されるのはReleaseバイナリ。(当然だが)
 結果は****ddとなる。(ブレークポイント等で止めて確認する)
2. そのReleaseバイナリをコマンドプロンプトから起動すると、****deの結果が得られる。
0191デフォルトの名無しさん垢版2018/09/15(土) 20:37:06.43ID:UR1d6CKz
ソース:
#include "stdafx.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];
norm = sqrt(norm);
if (regulate) for (int i=0;i<num;i++) r[i] = (T)(r[i]/norm);
return norm;
}

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,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000};
double* inputs = (double*)inputs_hex;
double norm = calc_norm_and_regulate(count, inputs, false);
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;
}
0192デフォルトの名無しさん垢版2018/09/15(土) 20:42:48.06ID:UR1d6CKz
オプション等(コマンドライン):(全てデフォのままのはずだが一応)
C/C++:
 /GL /D "WIN32" /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /FD /EHa /MD /Yu"stdafx.h"
/Fp"Release\test_floating_error4.pch" /Fo"Release\\" /Fd"Release\vc90.pdb"
/W3 /nologo /c /Zi /clr /TP /errorReport:prompt /FU "c:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll"
/FU "c:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll"
/FU "c:\Windows\Microsoft.NET\Framework\v2.0.50727\System.XML.dll"
リンカ:
/OUT:"MYPATH\test_floating_error4\Release\test_floating_error4.exe"
/INCREMENTAL:NO /NOLOGO /MANIFEST
/MANIFESTFILE:"Release\test_floating_error4.exe.intermediate.manifest"
/MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG
/PDB:"MYPATH\test_floating_error4\Release\test_floating_error4.pdb"
/LTCG /DYNAMICBASE /FIXED:No /NXCOMPAT /MACHINE:X86 /ERRORREPORT:PROMPT

パスは$MYPATHと書き換えた。また、投稿の為に適宜改行を入れた。
このプロジェクト名は見れば分かるとおりtest_floating_error4。
0193デフォルトの名無しさん垢版2018/09/15(土) 20:43:03.84ID:UR1d6CKz
備考2:
なおこの方法で見える calc_norm_and_regulate 関数の『逆アセンブル』結果は
俺の環境での物とコールアドレス以外は一致していることを確認している。
一応、diff結果は以下。
8c8
< 0000000c cmp dword ptr ds:[00752E14h],0
---
> 0000000c cmp dword ptr ds:[007D2E14h],0
10c10
< 00000015 call 676F58B9
---
> 00000015 call 683C58B9
44c44
< 0000006a call FF0455E8
---
> 0000006a call FFD955E8
0194デフォルトの名無しさん垢版2018/09/16(日) 02:47:43.28ID:wIV2HUNW
>>190
C++/CLR では、.Net を使っているから、起動方法が違うだけでも、
fpu control word の値や、使うCPU命令がx87 FPUなのか、SSE
なのかが違ってくる可能性があるかもしれない。

fpu control word は、main()関数に入る前の start up codeの中で
初期化される。
0195デフォルトの名無しさん垢版2018/09/16(日) 03:19:36.22ID:wIV2HUNW
>>191
// Release build
// 0.000000, 0x1ff68ddfb62221dd from IDE
// 0.000000, 0x1ff68ddfb62221de from command prompt

それにしても、随分小さな値だね。ちなみに、浮動小数点表示
の場合の有効数字の桁数を上げたら、どのようになる?
1.xxxe-yy
表示にして。
0196デフォルトの名無しさん垢版2018/09/16(日) 03:40:33.66ID:wIV2HUNW
>>191
試しに、ソースの冒頭に
#include <stdio.h>
を追加してから、

Console::Write(String::Format("{0:F6}, 0x{1:x16}\r\n",norm, *(__int64*)&norm));
の部分を、

printf( "%30.30e, 0x%016X\n", norm, *(__int64*)&norm) );

としてみるとどうなる?
0198デフォルトの名無しさん垢版2018/09/16(日) 07:27:22.50ID:SOVIz+sV
> 0x1ff68ddfb62221dd(Debug)
> 0x1ff68ddfb62221de(Release)

VS 2010 VC++ Express でも再現した
0199デフォルトの名無しさん垢版2018/09/16(日) 07:38:10.70ID:SOVIz+sV
↓このループを抜けたあと、すでにReleaseビルドとDebugビルドでは
 normの値に差異が発生してることが確認できた
for (int i=0;i<num;i++) norm += (double)r[i] * (double)r[i];

↓この下に(ループ内に)fprintf文を入れるだけで
 ReleaseビルドとDebugビルドが同じ実行結果になることが確認できた
norm += (double)r[i] * (double)r[i];

とりあえずまずこれだけは分かったから
低学歴知恵遅れが書いたウンココードの問題箇所を限定する
0200デフォルトの名無しさん垢版2018/09/16(日) 07:51:03.41ID:SOVIz+sV
@-1 デフォルト設定(Release)

【コード】

#include "stdafx.h"
#include <stdio.h>
#include <stdint.h>
#include <math.h>

int main(array<System::String ^> ^args)
{
  __int64 inputs_hex[16] = {
    0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x1fedb1530240aa54,
    0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x1ff0af0d95025bc3,
    0x1fc9353df6af376b, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
    0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000
  };
  double* r = (double*)inputs_hex;
  double norm = 0;

  for (int i = 0; i < 16; i++) {
    norm += (double)r[i] * (double)r[i];
//    fprintf(stdout, "[1]0x%016llX:%.19lg\n", *(uint64_t*)&norm, norm);
  }
  fprintf(stdout, "0x%016llX:%.19lg\n", *(uint64_t*)&norm, norm);
  return 0;
}
0201デフォルトの名無しさん垢版2018/09/16(日) 07:51:56.62ID:SOVIz+sV
@-1 デフォルト設定(Release)

↓このコードの逆アセンブルコード
https://ideone.com/Ryyxkl

【実行結果】

0x0007F2C44DFFF8F2:1.1053482540585106e-308
0202デフォルトの名無しさん垢版2018/09/16(日) 07:53:20.79ID:SOVIz+sV
@-2 デフォルト設定(Release)

#include "stdafx.h"
#include <stdio.h>
#include <stdint.h>
#include <math.h>

int main(array<System::String ^> ^args)
{
  __int64 inputs_hex[16] = {
    0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x1fedb1530240aa54,
    0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x1ff0af0d95025bc3,
    0x1fc9353df6af376b, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
    0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000
  };
  double* r = (double*)inputs_hex;
  double norm = 0;

  for (int i = 0; i < 16; i++) {
    norm += (double)r[i] * (double)r[i];
    fprintf(stdout, "[1]0x%016llX:%.19lg\n", *(uint64_t*)&norm, norm);
  }
  fprintf(stdout, "0x%016llX:%.19lg\n", *(uint64_t*)&norm, norm);
  return 0;
}
0203デフォルトの名無しさん垢版2018/09/16(日) 08:02:12.99ID:SOVIz+sV
@-2 デフォルト設定(Release)

↓このコードの逆アセンブルコード
https://ideone.com/4j12ib

【実行結果】

↓実行結果を書き込めないからこっちに書き込んどいた
https://ideone.com/gOqtki

0x0007F2C44DFFF8F1:1.1053482540585101e-308
0204デフォルトの名無しさん垢版2018/09/16(日) 08:05:50.92ID:SOVIz+sV
A-1 最適化無効 (/Od)(Release)

※ コードは@-1(>>200)と同じ

↓このコードの逆アセンブルコード
https://ideone.com/cONCAx

【実行結果】

0x0007F2C44DFFF8F1:1.1053482540585101e-308
0205デフォルトの名無しさん垢版2018/09/16(日) 08:09:59.78ID:SOVIz+sV
A-2 最適化無効 (/Od)(Release)

※ コードはA-2(>>202)と同じ

↓このコードの逆アセンブルコード
https://ideone.com/kuRt3w

【実行結果】

※ @-2(>>203)と同じ

0x0007F2C44DFFF8F1:1.1053482540585101e-308
0206デフォルトの名無しさん垢版2018/09/16(日) 08:20:27.67ID:SOVIz+sV
@-1、@-2の逆アセンブルの出力結果を比較すると原型をとどめてないぐらいグチョグチョに違う(最適化のせいと考えられる)
A-1、A-2の逆アセンブルの出力結果を比較すると差異はほとんどない(Aは両方ともまったく最適化されてないから当然)

@-1とA-1の逆アセンブルの出力結果を比較すると原型をとどめてないぐらいグチョグチョに違う(@-1のコード(>>200)ははげしくウンコ最適化されてると考えられる)
@-2とA-2の逆アセンブルの出力結果を比較すると差異はほとんどない(@-2のコード(>>202)はあまり最適化されてないと考えられる)

はっきりいって、これ以上見る気もしないしテキトーだが
ウンコみたいな最適化で演算の順序が入れ替わったせいで、誤差が発生しているものと考えられる
0207デフォルトの名無しさん垢版2018/09/16(日) 08:28:37.25ID:zL1WUjLu
>>198以降、
すまん、入れ替わりになるかもしれんが後で確認する。
まず>>194その他について回答する。

>>194
SSEは /arch:SSE または /arch:SSE2 でないと出ないことになっており、勿論設定はしていない。
また、逆アセンブル結果では x87 命令のみであるのも確認している。
ただ今回の問題は、本当にReleaseビルドのバイナリを逆アセンブルしているか怪しい事だが。

>>195
小さい値なのは偶々だ。
辿って行ってそれが1回目にヒットする入力データだっただけのこと。

>>196
.NETの書式指定はググり難いが以下。
https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings
概ねprintfと同じで、自動的にやってくれるのが増えている。
30桁欲しければ以下。
Console::Write(String::Format("{0:E6}, {0:E30}\r\n",norm));
// 出力は 1.051355E-154, 1.051355436595307800000000000000E-154
なおdoubleは16桁な。(15.9=53*log(10)2)

ただ当たり前だが、書式を変えたところで計算結果は変わらないし、
精度の問題には関係ない。
0208デフォルトの名無しさん垢版2018/09/16(日) 08:29:03.14ID:zL1WUjLu
>>194
FPU control registor については何故か安定した結果を得られていない。
インラインアセンブラは以下の通りで、

#pragma unmanaged
inline void fpu_getcw(unsigned short* cw) {
__asm{
fnstcw [cw];
}
}
#pragma managed

これを norm = calc_norm_and_regulate( ... ) の直前/直後に配置して読み出し、
同様にコンソール出力すると、以下となる。
また、IDEで起動した場合は、「レジスタ」で見れる。
なお定義は以下の通り。
[9:8]に対し、
0x00 : 単精度(24bit)
0x01 : reserved
0x10 : 倍精度(53bit)
0x11 : 拡張倍精度(64bit)
[11:10]に対し
0x00 : 最近値
0x01 : 切り捨て
0x10 : 切り上げ
0x11 : 0方向への切り捨て
0209デフォルトの名無しさん垢版2018/09/16(日) 08:29:57.53ID:zL1WUjLu
>>194
直後のみに配置:
0x027F (倍精度) = Debug(IDE起動)のIDE内表示、Release(IDE起動)のIDE内表示、
0x03a5 (拡張倍精度) = Debug(IDE起動)、Release(IDE起動)、
0x3fdc (拡張倍精度) = Debug(コマンドプロンプト)、
0xf280, 0xf290, 0xf160, 0xf010等、不安定 = Release(コマンドプロンプト)

直前のみに配置:
直後のみと同じ結果。(つまり『何故か』安定している)
Release(コマンドプロンプト)は不安定なのも同じ。

直前と直後に配置:
直前側は当然不安定になる。
直後側は「直後のみ」の結果と同じ。(Release(コマンドプロンプト)は不安定なのも同じ)

雰囲気からすると、IDE内表示は当てにならず、
命令自体は rdtsc と同じで非同期に実行されている雰囲気だが、
rdtsc命令の注意書きにある「シリアル化命令ではない」という但し書きが無く、状況は不明。
正直、正しく読み出せているか怪しい。(あてにならない)
これらから推測すると、暫定的には以下。

拡張倍精度 = Debug(IDE起動)、Release(IDE起動)、Debug(コマンドプロンプト)、
不明 = Release(コマンドプロンプト)


以上が>>194その他に対する回答。
これから>>198その他について確認する。
0211デフォルトの名無しさん垢版2018/09/16(日) 13:21:26.16ID:haV9TZ8e
>>209
>命令自体は rdtsc と同じで非同期に実行されている雰囲気だが、
>rdtsc命令の注意書きにある「シリアル化命令ではない」という但し書きが無く、状況は不明。
>正直、正しく読み出せているか怪しい。(あてにならない)

インラインアセンブラを使わずに、

_control87(), _controlfp() : Get and set the floating-point control word.

unsigned int _control87( unsigned int new, unsigned int mask );
unsigned int _controlfp( unsigned int new, unsigned int mask );

を使ってみたらどうなる?
0212デフォルトの名無しさん垢版2018/09/16(日) 13:31:15.50ID:Q5j4SiHR
win32コンソールなら結果が同じ。 もう理由は分かったのに何が問題なんだ?こんなの何の影響もないだろう。
0213デフォルトの名無しさん垢版2018/09/16(日) 13:33:14.92ID:zL1WUjLu
>>198
再現実験ありがとう。
しかし色々問題がある。

1. 俺は起動方法による違いについてフォーカスしているが、
 君はRelease/Debugの違いにフォーカスしている。
2. VC++2008では再現しない。(VC++2010では再現する)
3. ソース改変しすぎ。それでは意味がない。
4. >>206の結論は間違い。

まず問題なのはソースの改変だ。
ループ回数を16回と決め打ちしたことで 8*2 に展開されている。
その結果、元のソース(俺が遭遇した状況)では発生しえないことが発生している。
これでは意味がない。

そして、君の結論は間違いだ。
× > ウンコみたいな最適化で演算の順序が入れ替わったせいで、誤差が発生しているものと考えられる
逆アセンブルを追えば分かるが、演算順序は入れ替わっていない。
原因は、Debugでは fld/fmul/fadd/fstp と毎回64bitに整形されるのに対し、
Releaseでは (fld/fmul/fadd)*8 + fstp と整形が8回に1回と減り、
8回は80bit(拡張倍精度)で演算されるからだ。
(こうなったのは君が16回ループ決め打ちコードに改変したから)
ただしIDE上の fpu control registor の値は 相変わらず0x027F(倍精度)となっており、
IDEのこの表示が当てにならない事は分かる。

なおVC++2008では再現しなかった。
俺の環境では、16回決め打ちコードでも 8*2 に展開されず、Debugと同じコードだからだ。
勿論結果も同じだった。
0214デフォルトの名無しさん垢版2018/09/16(日) 13:33:48.22ID:zL1WUjLu
>>198
問題は、俺の環境で俺が提供したコード>>191だと、
同様に展開されないにも関わらず、『起動方法によって』結果が異なってしまう点だ。
俺の環境でのRelease/Debugの逆アセンブル結果のdiffは以下。
17c17
< 0000000c cmp dword ptr ds:[001C2E14h],0
---
> 0000000c cmp dword ptr ds:[00702E14h],0
19c19
< 00000015 call 68302BA9
---
> 00000015 call 683A5AB1
93c93
< 0000015a call FF6C3098
---
> 0000015a call FFCA57E8
98c98
< 0000016f push 0B5311Ch
---
> 0000016f push 0D03188h
104,105c104,105
< 00000183 push 4F9D68h
< 00000188 call FF6C30A4
---
> 00000183 push 2B71C0h
> 00000188 call FFCA57F4
アドレスの変更だけであり、君の結果
「ループ回数を決め打ちしたことによりアンローリングされ、一部の演算がx87精度で計算される」には該当しない。
そして、この状況でも結果が異なってしまうことが問題なのだ。

君は君が勝手に新しく作り込んだ問題に対し、間違った結論でお茶を濁したにすぎない。
君が知っているFPU関連のことはこちらも知っている上で、質問している。
0215デフォルトの名無しさん垢版2018/09/16(日) 13:53:17.67ID:haV9TZ8e
>>213
なるほど、全く別の2つの理由で、精度が変わっている可能性(というより多分、確実)があると。

それは以下の2つ:

1. Debug版とRelease版では、最適化の結果、x87 FPU命令の使われ方が変わる。
  x87では、メモリに書き戻さずに st(0)〜st(7)レジスタに入っている途中では、
 拡張倍精度の80BITで計算されるが、書き戻すとdoubleの場合でも64BITに丸め
 られる。なるべくメモリに書き戻さずにレジスタった方が高速なので、Release版
 では、80BITで計算される「期間」が多くなる。そのため、Debug版とRelese版では
 結果が僅かに違ってくる。

2. fpu control word が違っていて、st(0)〜st(7)に入っていても、計算が
 80BITか、64BIT、32BITのどれで計算されるか異なったり、丸め方が四捨五入
 か、正負二種類の方向の切り捨てなどが変わっている。


そして、IDEから起動した場合と、コマンドラインから起動した場合で結果が違う
のは、「2.」の理由によるものではないかと。そして、実際に、インラインアセンブラ
で fpu control word を読み取ってみると、不安定な値が読み出されたと。
0216デフォルトの名無しさん垢版2018/09/16(日) 13:58:15.86ID:haV9TZ8e
まず、
__asm{
 fnstcw [cw];
}
ではなく、_control87() を使ってみて欲しい。

インラインアセンブラは、独立した *.asm で書くより危険な場合が
あるかも知れないので。特にC関数の引数、今の場合は、「cw」を
インライン・アセンブラで用いた場合、正しいコードが出ているかどうか
は注意が必要。
0217デフォルトの名無しさん垢版2018/09/16(日) 14:05:28.41ID:haV9TZ8e
>>208
よく見ると、それは、かなり複雑な事情が絡みそうなコード。
以下のようにした方が安心。なお、「cw」という短すぎる引数名
も長年のプログラミング経験からすると、インラインアセンブラでは
怖い。また、

TTTT reg,引数名

TTTT 引数名
は大丈夫でも、
TTTT reg,[引数名]

TTTT [引数名]
は1命令では不可能な事をコンパイラに指示している事になるので
ちょっと怖い。間接の間接、つまり、[[ebp+8]]みたいな事を要求
しているが、そんなオペランドが使えるアセンブリ命令はx86/x64
では存在しないので。


#pragma unmanaged
inline void fpu_getcw(unsigned short *pCW) {
 __asm{
  mov edx,pCW
  fnstcw [edx];
 }
}
#pragma managed
0218デフォルトの名無しさん垢版2018/09/16(日) 14:17:40.34ID:haV9TZ8e
あ、後、インライン・アセンブラで実験する場合は、関数名の inline は
「取った」方がいい。つまり、以下の方が安心:

#pragma unmanaged
void fpu_getcw(unsigned short *pCW) {
 __asm{
  mov edx,pCW
  fnstcw [edx];
 }
}
#pragma managed
0220デフォルトの名無しさん垢版2018/09/16(日) 15:37:02.44ID:Q5j4SiHR
.netはx87コンテキストをすべて保持しませんって分かったんだからもう十分。
win32かx64にすれば解決。そもそも問題になる仕様バグじゃない。
0221デフォルトの名無しさん垢版2018/09/16(日) 15:40:56.17ID:haV9TZ8e
>>219
ホントだ。/MDだと、Runtime Library として DLL のものを使ってしまう。
これは、今回の現象に非常に重要な影響を与えているかも知れない。
0223デフォルトの名無しさん垢版2018/09/16(日) 15:48:45.63ID: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 が読み出される。
ただし、これは上記の仕様からして、当てにならない。
0224デフォルトの名無しさん垢版2018/09/16(日) 15:49:44.99ID: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でもしているのか?
まあこれに当たっているのなら確実に俺のバグだし、これなら辻褄は合ってしまうのだが。
0225デフォルトの名無しさん垢版2018/09/16(日) 15:51:01.50ID: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の一部しか使えない、ということか?
0226デフォルトの名無しさん垢版2018/09/16(日) 15:51:25.16ID: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] だ。
理由は分からんがこちらだと安定しているので、結果としてはこのやり方が正しい。
0227デフォルトの名無しさん垢版2018/09/16(日) 16:02:47.64ID:haV9TZ8e
>>225
をを。やはり、ある意味ではVCが間違ったアセンブリコードを出していたよ。
それだと、
fnstcw [EBP+08]
という意味になってしまって、
fnstcw pCW
の意味になっている。つまり:
pCW = control_word;
あなたが、やりたいのは、
*pCW = control_word;
だったのだから、アセンブリ・コードが間違ってる。

あなたが指示したのは、
fnstcw [pCW]
だった。実際に生成されたコードは、
fnstcw pCW
だった。

VC のインラインアセンブラは、エラーも出さずに間違ったコードを
出すことが証明された。

これと、精度が不安定な問題とは全く別ではあるけれど。
0228デフォルトの名無しさん垢版2018/09/16(日) 16:06:05.39ID:zL1WUjLu
すまん、間違いの修正

>>224
× > どうやらこれが原因の可能性が出てきた。(はっきり言って俺のバグだが)
× > まあこれに当たっているのなら確実に俺のバグだし、これなら辻褄は合ってしまうのだが。

今回は俺はあくまで俺の本番コードのデバッグを念頭に置いていて、この発言だった。
ただし>>191の再現コードで『不定スタック領域』を掴んでいるわけもなく、
一応IDE起動とコマンドプロンプト起動での挙動の違いを再現出来ているわけだから、
これだけが問題ではないのも事実だ。

俺にとっては一つ新しい知見として、
・IDEから起動した場合、スタックが初期化されるっぽい
ということが分かった。とはいえOSは0fillしてから各プロセスにメモリを与えるので、実際は、
・コマンドプロンプト起動ならmain前に設定した続きでそのまま実行、
・IDE起動ならmain前に色々やって0fillして実行、
 或いはmain前に色々やることが多く、スタックが進み、(例えばデバッガをアタッチする為)
 結果的にOSが初期化済みの領域から始動
となって違いが発生するというところか。
0229デフォルトの名無しさん垢版2018/09/16(日) 16:11:52.18ID: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 は特に危険。
0230デフォルトの名無しさん垢版2018/09/16(日) 16:17:02.07ID:haV9TZ8e
>>228
>ただし>>191の再現コードで『不定スタック領域』を掴んでいるわけもなく、
>一応IDE起動とコマンドプロンプト起動での挙動の違いを再現出来ているわけだから、
>これだけが問題ではないのも事実だ。

そうだよ。精度が変わるのはあなたの間違いではない。スタック領域が0クリア
されようがれまいが、あなたのコード自体には特に不安定さはない。
非初期化領域を参照しているコードは見当たらないし。
0231デフォルトの名無しさん垢版2018/09/16(日) 16:20:22.27ID:haV9TZ8e
逆アセンブラ結果を見てないで言うけど、もし、sqrt() が call文で関数呼び出し
されているんだったら、そこで精度の違いが出てるかもしれない。
0232デフォルトの名無しさん垢版2018/09/16(日) 16:23:20.75ID:zL1WUjLu
>>227
なるほど、了解した。
つまり、>>209は全面的に間違いで、正しくは、

・fpu control register は 0x027F で、IDEからも正しく読めている

だな。


俺がやるべきだったのは fnstcw [[cw]] なのだと思うが、これはSyntaxErrorだ。
そして、こんな命令はないから、
[]内に変数を書かず、レジスタ名にしろ、ということだったのだな。
全くもって了解だ。

VCの問題ではなくて、
俺が fnstcw [cw] と書いたのが間違いで、それをそのままコードにされてしまっただけだな。
正しく書けばSyntaxErrorだったのだし。
なお fnstcw [*cw] もSyntaxErrorだ。手動で一旦レジスタに移さないと駄目だな。
全くもって>>218のコードが正しい。
0233デフォルトの名無しさん垢版2018/09/16(日) 16:35:08.59ID: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;

としたということ。
0234デフォルトの名無しさん垢版2018/09/16(日) 16:36:04.13ID:zL1WUjLu
>>229-230
了解だ。ありがとう。

>>231
その部分の逆アセンブラは以下の通り。
普通にcallされている。(行数オーバーなので切るが)

ただし、
> そこで精度の違いが出てるかもしれない
との繋がりがよくからない。
sqrt()でcallされると、スタックが改変される。おそらくデータ依存か?
なら未初期化のスタックを掴みに行っているコードが有ればバグる。
ただし今回の『再現コード』はこの限りではない。
(俺の本番コードはさておき)
0235デフォルトの名無しさん垢版2018/09/16(日) 16:37:19.30ID: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]
0236デフォルトの名無しさん垢版2018/09/16(日) 16:37:34.94ID: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]
0239デフォルトの名無しさん垢版2018/09/16(日) 16:49:54.65ID:zL1WUjLu
>>237
いや、俺が提供した>>191のソースなら使われてるぞ。
>>200のソースでは使われてないが。

ただまあ、彼(200)がsqrtを落としたのも分からなくはない。
誤差が生じる=通常は桁落ちだから、この場合は当然積和部分が怪しい。
あらかじめ彼はそうなると分かっていてそれを落とし、予定調和的な結論にたどり着いてしまった。
それが彼の間違いだった、ということ。

俺は出来るだけ元のソースのままで追跡しようとしている。
元のソースの該当ケースと離れてしまっては意味がないから。
そして元ソースではsqrtを使っている。
0240デフォルトの名無しさん垢版2018/09/16(日) 16:53:58.12ID:/oSJzlqn
たぶん2008の最適化ミスだと思う。
static double norm = 0;// ←"static"を追加する
にするとか、最適化オプションをいじると
Release/コマンドプロンプトからの起動でも
0x1ff68ddfb62221ddになる
0241デフォルトの名無しさん垢版2018/09/16(日) 16:54:10.71ID: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 文によって
実際に本当のサブ・ルーチンを呼び出していると。

これはとても興味深い。そのサブ・ルーチンの中が、時と場合によって
精度が変わってくるような書き方をされている可能性が見えてきた。
0242デフォルトの名無しさん垢版2018/09/16(日) 16:56:42.67ID:LrdaMWHl
>>239
>いや、俺が提供した>>191のソースなら使われてるぞ。
> >>200のソースでは使われてないが。

了解。

問題を切り分けるため、sqrt() を使わなかった場合の Release版での、
IDE起動とコマンドrライン起動の精度の違いを実験してみて欲しい。
0244デフォルトの名無しさん垢版2018/09/16(日) 17:22:07.21ID: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
0245デフォルトの名無しさん垢版2018/09/16(日) 17:22:29.32ID: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]
0246デフォルトの名無しさん垢版2018/09/16(日) 17:22:46.06ID: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
0247デフォルトの名無しさん垢版2018/09/16(日) 17:35:35.70ID: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分くらいでちょっと離れる予定。
0248デフォルトの名無しさん垢版2018/09/16(日) 18:30:34.19ID:HF0YmRsW
>>212
ほんそれ
0249デフォルトの名無しさん垢版2018/09/16(日) 20:54:27.39ID: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]
0250デフォルトの名無しさん垢版2018/09/16(日) 21:25:23.90ID:zL1WUjLu
>>219
>>221
/MTと/clrは同時に指定出来ないらしい。(error D8016)
/MTdも同じく無理。

もう一つ /MDd ってのがあるから試してみた。

/MDdの結果:
Releaseビルドでコマンドプロンプト起動の時のみ ****de、
ReleaseビルドでIDEからの起動だと ***dd。(Debugビルドは起動方法を問わずこっち)
(/MDと全く挙動は同じ)


これで有効な指摘については全て回答してるかな?
見落としが有れば指摘よろしく。
(規制に引っかかったので遅くなってすまん)


今のところ、可能性があるのは以下か?

・Releaseビルドをコマンドプロンプトから起動したときのみなぜか精度が高い
 (>>200から結果的に検出された。今のところ精度が高いときと同じ挙動をしている為)
・ReleaseビルドもIDEから起動すれば結果的にスタックが0初期化されている状態になっており、
 俺の本番プログラムに関してはここに当たるバグがある?(>>228)
 (ただしこれは>>191には該当しない)
0251240垢版2018/09/16(日) 21:43:04.47ID:/oSJzlqn
.netの場合、デバッガ配下では(デバッグのため)違うコードを実行しているような気がする。
デバッガの逆アセンブル表示とかasm出力はあまり当てにならないような気もする。
ループ部分だけど、レジスタのみで処理するか、メモリを使用するかで精度が変わるのかも。
そもそも、どっちが正しいのかよくわからんけど...
ループ部分の関数を#pragma unmanagedすると結果が変わるでそれが正しいのかも。
0252240垢版2018/09/16(日) 21:43:27.78ID:/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
0253デフォルトの名無しさん垢版2018/09/16(日) 22:27:34.58ID: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];
0007272C 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)
0254デフォルトの名無しさん垢版2018/09/16(日) 22:33:32.07ID: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 m64fp [disp32] であり、そこで64bit(倍精度)に丸められてる。
だからレジスタ(80bit=拡張倍精度)で演算される非static版と結果が異なる。
static版のsftpが DB /7 m80fp なら誤差は出ないはずなんだよ。(Cでどう書くのかは知らん)

だから>>252の場合の誤差なら、仕様通りなんだよ。(片方が倍精度、もう片方は拡張倍精度)
ただし、>>191は逆アセンブル(>>235)を見る限りそれに該当しないし、(両方とも倍精度)
今回の俺の上記逆アセンブル(>>253、中身は君の指摘通りunmanagedにしただけ)も該当しない。(両方とも倍精度)
そして253は何故か直ってしまった。
0255デフォルトの名無しさん垢版2018/09/16(日) 22:34:16.44ID:zL1WUjLu
>>252
> .netの場合、デバッガ配下では(デバッグのため)違うコードを実行しているような気がする。
> デバッガの逆アセンブル表示とかasm出力はあまり当てにならないような気もする。
これは俺も相当疑っているのだが、今のところ尻尾を掴めない。
ILspyだっけ?外部の逆アセンブルツール使えばチェック出来るのかな?

いずれにしても、>>251の指摘
・unmanagedにすれば直る
のも事実だし、逆アセンブルを見る限り、これを説明出来る理由もないのも事実。
0256240垢版2018/09/16(日) 23:13:48.62ID:/oSJzlqn
> だから>>252の場合の誤差なら、仕様通りなんだよ。(片方が倍精度、もう片方は拡張倍精度)
そうなの? これが仕様通りならstatic版での違いは仕様通りということになる。
252はRelease版をコンソールで実行したときの逆アセンブル結果。
よって、Release版をコンソールで実行したときのみ(たまたま)レジスタ(80ビット)での演算になるので、
計算結果が変わるのはやむを得ないという結論になるのだが...

ちなみに、235はDebugモードでコンパイルし、デバッガ配下の逆アセンブル結果でしょ。
0257デフォルトの名無しさん垢版2018/09/16(日) 23:24:30.83ID:zL1WUjLu
>>256
> 252はRelease版をコンソールで実行したときの逆アセンブル結果。
それはどうやって得たの?俺はそれが出来ないから困ってる。

> ちなみに、235はDebugモードでコンパイルし、デバッガ配下の逆アセンブル結果でしょ。
235は、IDE上でReleaseモードでF5で起動し、ブレークポイントを当てて止めて逆アセンブルした結果。
俺が貼ってる逆アセンブル結果は全てこの方法で、IDEで表示されているもの。
だからIDEの表示がおかしかったら話が全部おかしくなる。

君がIDEから独立して逆アセンブル出来ているのなら、その方法を知りたい。
こちらでも試す。


なおILSpy、グダグダ言わずに試してみたが、
当たり前だがmanaged code だとILが出る(x86ではない)ので、
俺って根本的に間違ってたかも?
今までx86のアセンブラで議論してたけど、これって .NET アプリには同梱されていないというオチ?
(まあその場合は君がやっている外部逆アセンブルが単純には出来ないはずなのだが)
0258240垢版2018/09/16(日) 23:35:36.48ID:/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で起動し、ブレークポイントを当てて止めて逆アセンブルした結果。

あれ? だとすると最適化していないのでは?
こちらの結果と違うのだが。
0259デフォルトの名無しさん垢版2018/09/16(日) 23:49:32.68ID:SOVIz+sV
とりあえず、>>198に書いてあるとおり、元のコードで再現はしてるからな
その再現したコードと逆アセンブルした結果はあげとく

B-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;
}
0260デフォルトの名無しさん垢版2018/09/16(日) 23:50:40.20ID:SOVIz+sV
B-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,
      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);
   // 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;
}
0261デフォルトの名無しさん垢版2018/09/16(日) 23:51:14.21ID:SOVIz+sV
B-1 デフォルト設定(Release) 【実行結果】

↓このコードの逆アセンブルコード
https://ideone.com/Gf4qUQ

[1]0x0007F2C44DFFF8F2:1.1053482540585106e-308
[2]0x1FF68DDFB62221DE:1.051355436595308e-154
0262デフォルトの名無しさん垢版2018/09/16(日) 23:54:13.85ID:SOVIz+sV
で、>>199に書いてあるとおり↓Debugビルドと同じ結果が再現された

> ↓この下に(ループ内に)fprintf文を入れるだけで
>  ReleaseビルドとDebugビルドが同じ実行結果になることが確認できた
> norm += (double)r[i] * (double)r[i];

B-2 デフォルト設定(Release) 【コード】(その1)

#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;
}
0263デフォルトの名無しさん垢版2018/09/16(日) 23:54:58.60ID:SOVIz+sV
B-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,
      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);
   // 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;
}
0264デフォルトの名無しさん垢版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

以上だ
0265デフォルトの名無しさん垢版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ビルドとも微妙にアドレス等が違うんだが。

とはいえ、これは「そもそも色々間違っている」可能性が出てきたので、もう一度全体を見直す。
明日(だけで済むとも思えないが)確認し、整理してまた投稿する。

とにかくありがとう。これはだいぶインパクトがある。(はず)
0266デフォルトの名無しさん垢版2018/09/17(月) 00:49:10.27ID:gBxGzBbQ
>>265
ideとconsoleで微妙に違うバージョンのvcruntimeがロードされてるとか?
process monitorで何が実行されて何がロードされてるか調べるとか?
あとはwindbgから起動したら、ideとconsoleのどちらの結果と一致するのか気になる。
0267デフォルトの名無しさん垢版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]
0268デフォルトの名無しさん垢版2018/09/17(月) 01:07:41.74ID:+dwRu2dr
>>261(続き)
これは少なくとも「ループ回数が8の倍数である」事がコンパイラに見えないと出来ない最適化だ。
そうでなければ、例えばループ回数が6回や14回の時に、
最初の1回だけ 0299 に飛び込んで始める(頭の2回をスキップする)コードが必要になるが、
それは出てないだろ。

(そもそもこのアンローリングがx86的に意味があるのかも疑問だが)
一般的に、可変回数ループを展開すると、必ず上記の端切れ処理(キリが良くないときの処理)が必要になる。
だから「可変」だと確定しているのなら普通は展開しない。
つまり、一般的には、別関数でループ回数が引数で与えられてたら、その最適化はかからない。

今回ヒットするデータが偶々16回ループだっただけで、
俺の本番コードは可変で用いている為、
このようなアンローリングはされてない。(と思ってる。ただし265の通りもう一度確認必要)
こちらではデフォでそこまで最適化がかからないのでそちらの状況はよく分からないが、
その最適化がかかってるのなら、俺の本番コードとは違う状況で動いていることになる。(はず)
だから俺はその最適化がかからない範囲で議論してる。
それが俺が最初から別関数にしてた理由。(というか元のコードが別関数だからだが)


てゆうかマジでそれデフォのままか?
もしかして俺の環境がおかしくて、全く最適化されてないコードが出てる?
0269247垢版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)へ
直されるタイミングや回数が変わる。

この両者では結果の精度が変わってくる。前者の方が後者より僅か
に精度が高くなる。
0270243=269垢版2018/09/17(月) 01:14:28.51ID:yaPtorLJ
>>269
名前欄は、「247」ではなく「243」の間違いだった。
0271デフォルトの名無しさん垢版2018/09/17(月) 01:24:06.04ID:yaPtorLJ
>>257
>なおILSpy、グダグダ言わずに試してみたが、
>当たり前だがmanaged code だとILが出る(x86ではない)ので、
>俺って根本的に間違ってたかも?
>今までx86のアセンブラで議論してたけど、これって .NET アプリには同梱されていないというオチ?

やはり、managed code部分は、x86命令では無く、ILにコンパイルされていて、
普通のC++とは違ってたんだ。
0272デフォルトの名無しさん垢版2018/09/17(月) 01:30:31.16ID:yaPtorLJ
>calc_norm_and_regulateをunmanaged関数にすると、違いはなくなる。
>(Releaseビルドの`をコマンドプロンプトで起動した際にも、****ddの結果となる)

やはり。
unmanaged関数の場合は、CIL(MSIL)ではなく、exeの段階で既に
x86マシン語に直されたものが格納されるんだろう。だとすると、起動方法に
関係なく、少なくともその部分に関しては、x87 fpu命令の使われ方が
全く同じになる。callしたsqrt()関数の中は除いて。
0273デフォルトの名無しさん垢版2018/09/17(月) 01:37:20.55ID:dj7qSZnZ
>>259-260のコードも>>262-263
も同じ条件でデフォルトでコンパイルしてる
コレは間違いない

一行コメントはずしてコンパイルしなおすだけだからな

で、>>261>>264みたいな結果になる
>>264の実行結果はDebugビルドとまったく同じになる
そのまんま
0274デフォルトの名無しさん垢版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 コンパイルされないといけないので、
起動速度が遅くなり、かつ、一般的に、システム・リソースの使用が増える。
0275デフォルトの名無しさん垢版2018/09/17(月) 02:49:02.18ID:dj7qSZnZ
普通のコンソールアプリケーション(CLRじゃないほう)でも
同じコードで普通にまったく同じように再現するワケだが

ホントなキミラはなにを頭悪いことばっかりいってんの?
実行結果だけははっといてやるが
0276デフォルトの名無しさん垢版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;
}
0277デフォルトの名無しさん垢版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;
}
0278デフォルトの名無しさん垢版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
0279デフォルトの名無しさん垢版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;
}
0280デフォルトの名無しさん垢版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;
}
0281デフォルトの名無しさん垢版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
0282デフォルトの名無しさん垢版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;
}
0283デフォルトの名無しさん垢版2018/09/17(月) 02:54:34.82ID:dj7qSZnZ
(正)>>282
(誤)>>279
0284デフォルトの名無しさん垢版2018/09/17(月) 02:57:46.48ID:dj7qSZnZ
>>276-277のコードも>>282,280のコードも
も同じ条件でデフォルトでコンパイルしてる

一行コメントはずしてコンパイルしなおすだけだからな

で、>>278>>281みたいな結果になる
>>281の実行結果はDebugビルドとまったく同じになる
そのまんま

CLRのとき(>>273)の動作とまったく同じ
キミラはずーっとなにやってるわけ?
0285デフォルトの名無しさん垢版2018/09/17(月) 09:44:34.76ID:yu1Dprt2
>>284
同一のreleaseをコンソールで実行するかデバッガで実行するかで結果が異なるのはなぜだろう。
という話をしていたのであって、
debug/releaseで別の結果になることを問題にしているのではないです。
0286デフォルトの名無しさん垢版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
確かにこのオプションで直った。
0287デフォルトの名無しさん垢版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についての疑問は解消した。(はず)
俺の本番コードについては再度確認し、また報告する。
0288デフォルトの名無しさん垢版2018/09/17(月) 10:28:21.54ID:dj7qSZnZ
同じリリースビルドで
結果がかわってんのになにいってんの?

fprintf入れるだけで
リリースビルドで結果が変わる
0289デフォルトの名無しさん垢版2018/09/17(月) 10:31:16.66ID:dj7qSZnZ
やはり低学歴知恵遅れは
結果が意味するところが分かってないわ。。。
0290デフォルトの名無しさん垢版2018/09/17(月) 10:32:49.39ID:dj7qSZnZ
ちなみにオレがあげた結果は
すべてリリースビルドの結果だからな
デバッグビルドの結果なんかあげても
意味ないからな
0291デフォルトの名無しさん垢版2018/09/17(月) 10:38:00.02ID:dj7qSZnZ
CLRのケースもCLRでない普通のexeのケースでも
結果はまったく同じだからな

しかもすべてリリースビルドで
おきてる誤差までぴったり一致してる
0292デフォルトの名無しさん垢版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するコードでも拡張倍精度で回っていたかもしれん。
勿論手動でそういうコードのすることも可能だ。
そこはコンパイラがどう判断したのかでしかなく、あまり詰めても意味がない。
0294デフォルトの名無しさん垢版2018/09/17(月) 10:57:31.99ID:dj7qSZnZ
で、最適化されてるかされてないかすら
いまのいままで気付くことすらできない
そして気付く方法すらわからなかったわけか

うあわ
頭わるう。。。

キミ、プログラムくむの向いてないわ
0295デフォルトの名無しさん垢版2018/09/17(月) 10:58:47.63ID:dj7qSZnZ
問題の切り分けができない人は
プログラムはくめない

コレは定説だからな
0296デフォルトの名無しさん垢版2018/09/17(月) 11:09:05.96ID:ivGPGa/P
>>286
なるほど面白いね。

レスが膨大過ぎて最初の方しか読んでなかったけど、ネイティブコードの話と思い込んでたら
.NETの話だったのかw
0297デフォルトの名無しさん垢版2018/09/17(月) 12:34:14.16ID:yaPtorLJ
個人的には、C++やx87 FPUは割と知識があったけど、.NET関連は余り追いかけてなかったので、気づくのが遅れた。

managedコード、unmanagedコードについて、今回初めて調べてみたくらいだし。
0299デフォルトの名無しさん垢版2018/09/17(月) 13:39:23.91ID:F2vzl5VC
最初に指摘されたことだろうに。
アセンブラレベルで精度や効率に介入したきゃ.netなんて使うな、なんて分かりきったこと。
0300デフォルトの名無しさん垢版2018/09/17(月) 14:58:46.52ID:zCVYDMXL
エディタ使ってるとたまに Intellisense機能が効かないときがあるんだが
あれなんなの?
中間ファイルとか消せば直るの?
0303デフォルトの名無しさん垢版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]
0304デフォルトの名無しさん垢版2018/09/19(水) 17:24:44.24ID:GzaYiinu
VC++2008だけど、突然一部のファイルだけブレークポイントが入らなくなった・・・
.ncb消したり、そのプロジェクトだけリビルドしたけど直らない
全リビルドすればおk?
0305デフォルトの名無しさん垢版2018/09/19(水) 18:59:08.26ID:KTUM/Tgt
>>304
根本的な解決策とは違うが
「ブレークポイントは現在の設定ではヒットしません。ソースコードが元のバージョンと異なります。」
なら
[オプション] の[デバッグ]から[元のバージョンと完全に一致するソース ファイルを必要とする] をオフで
0306デフォルトの名無しさん垢版2018/09/20(木) 12:44:39.12ID:rLmEYUhk
>>305
ありがとうございます。

結局、全リビルドでも直らなかったので、.sln と .vcproj 以外全部消して
Windowsも再起動して完全にまっさらな状態にして全ビルドしたら直りましたが、
そのうちまたブレークポイントが入らなくなったので、>>305の方法で
回避しました。
0307デフォルトの名無しさん垢版2019/06/19(水) 14:12:16.93ID:Yoy0IPRe
お、おう
0308デフォルトの名無しさん垢版2019/10/04(金) 14:14:25.88ID:gozwERy2
C++ CLRのWindowsフォームアプリ作ってると、
イベントとか記入するときインデントがおかしい(スペースが1つ付く)んですが、
これを直す方法ってありますか?
0311デフォルトの名無しさん垢版2021/04/20(火) 20:00:45.05ID:rVJPu0WM
わからないので教えてください。
シリアル通信をするプログラムを作りたく、
VS2008にて、「SerialPort」を使え、というのが
サイトにあったのですが、
ツールボックスにSerialPortがありません。
追加する方法を教えてください。

使用環境:VS2008 C++ MFCアプリケーション
0313デフォルトの名無しさん垢版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)はあり得ないくらいの異常さだ。
お前が初心者で何も知らないだけなら、常に最新の環境を使うように心がけろ。それだけで無駄なことに嵌りにくくなる。
その環境に拘る何らかの理由があり、それを強いてきた上司等が居るのなら、まずそいつに聞け。
聞く人が居ないのなら、今のお前にその環境でやりきる能力はないから諦めろ。
レスを投稿する


ニューススポーツなんでも実況