リリースビルドで遅くなる

このQ&Aのポイント
  • リリースビルド時の速度がデバッグビルドよりも遅くなる問題が発生しています。特にメモリマップドファイルの処理に関連している可能性があります。
  • デバッグビルドではキャッシュの効果により、同じ処理を繰り返しても処理時間が短縮されますが、リリースビルドでは繰り返しても処理時間が変わりません。
  • この問題はキャッシュの方式に関連している可能性があります。Windows APIなどを使用してキャッシュの処理を改善することで解決できる可能性があります。
回答を見る
  • ベストアンサー

リリースビルドで遅くなる

非常に大量のコードを書いた後で気づいたので 挙動からおそらくその辺だと「思われる」のですが Windows XP SP 3で、Visual C++で デバッグビルド・リリースビルドしたときの速度を比較してみると おそらく、メモリマップドファイル絡みの個所で  現状なぜかリリースビルドの方が遅くなります。 巨大なファイルを1度扱ってから再度ほぼ同じ個所を使用した時 デバッグビルドではその間にアプリケーションを1度終了したとしても、その後別に巨大なファイルを使ったりしなければ どうもシステム的に(?)何らかのキャッシュが効いているようで 1回目で23秒程度かかる処理が、2回目以降は7秒弱で出来てしまいます。 (これは100回やったら99回以上はなるんでは?というくらい安定しています) 対してリリースビルドでは 最初の1回は同じくらいですが 2回目以降でも16秒程度はかかってしまう感じです。 なお、そのけた外れに長い演算の末に出来上がるfloatの配列は、デバッグビルド・リリースビルドで端から端まで完全に一致する、という確認もできています。 アプリ的に 2回目以降の時間を短縮できた方が非常に都合が良いのですが ビルドの設定はほとんど同じですが、これは仕様でしょうか? もしこれがキャッシュの方式の問題、であるのなら Windows APIなどを使うことにより対処可能な問題でしょうか? あるいは、デバッグビルド・リリースビルドの違いによるものではなく このアプリケーションのデバッグビルドによって出来た実行ファイルの方に 以前関連付けを行ったりするように(アイコンや、独自ファイル形式ダブルクリックで開けるように) レジストリを書き換えたのですが これによってシステムから「なんらかの優先事項」を享受できるようになっているため だったりする、という可能性もあるのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • 5S6
  • ベストアンサー率29% (675/2291)
回答No.1

VCのVerがわかりませんが、昔経験があります。 確かリンカのオプションでサイズ重視、速度重視とかの設定を変えると速くなりました。 ポインタをたくさん使う場合は速度重視の方が速かった気がします。 ほかにもマニフェストの組み込みとかいろいろ設定があるのでいじってみてください。 デフォルトだとコマンドラインからコンパイルした方がサイズが小さく高速です。 cl でコンパイルリンクします。

LongSecret
質問者

お礼

ありがとうございます♪ (バージョンは色々あってまだ2008EEです) リリースサイドも3度は確認したので デバッグ同様速度重視に合わさってた気がしたのですが 気になったのでサイズ重視に変更してみました。 すると!! 797KB(デバッグ側速度重視) ↓ 690KB(リリース側これまで) ↓ 431KB にまでなりました。 すごいですねこれ すると! 2度目以降9秒弱程度で出来るようになりました! そこで今度は「最大限の最適化」に すると 616KBに。 そしてなんと 7秒弱程度で出来てしまいました! しかし、なぜでは「速度重視」でダメなのか… と思い、再度「速度重視」に設定すると・・・ 606KBに!! あれ? あれええ!? そしてこれも 7秒弱程度で出来てしまいました! 確かに確認したのですが 今改めてそこんとこいじってどこに設定してみても 「細い文字」に戻りません。 もちろん「無効」に戻しても太字のままです。 ただし、無効にしたら 690KBと、同じ実行ファイルサイズになりました。 という事は、単に見間違いだったか あるいは、それよりは低い確率で、もしかしたら 何らかの理由により「細字になっていた」ために 誤作動していた(?) のかもしれません。 いずれにしても、一応解決という事になってしまいましたが VC++の仕様は知っておきたいので >デフォルトだとコマンドラインからコンパイルした方がサイズが小さく高速です。 >cl でコンパイルリンクします。 この部分は、具体的にはどういう手順を踏めばいいのでしょうか?

その他の回答 (2)

  • 5S6
  • ベストアンサー率29% (675/2291)
回答No.3

スタートメニューにVisual Studio コマンド プロンプトってありますよね。 cl /? とやれば最適化のオプションがたくさんでてきます。 プログラムの性質により最適化が異なるのでいろいろやってみましょう。 SSE3を使う設定や64bitコンパイルすれば更に速くなりますよ。 /arch:SSE3 など 他にはソースの変更が必要ですがマルチスレッドにすれば速くなります。 それとメモリを多く積んでいる場合に限りますが・・・ Windows7で8GB,16GBなどの場合、スワップファイル(仮想メモリ)を使用しない。 設定にすれば、なんじゃこりゃ!?と思うほど速くなります。 fpsなどのゲームで体験すると数倍起動が速くなりますし。 ちなみに昔C++のプロジェクトで40分かかる計算を10秒台まで最適化したことあります。 簡単なことで意外と速くなりますよ。

LongSecret
質問者

お礼

どうもどうも >他にはソースの変更が必要ですがマルチスレッドにすれば速くなります。 これに関しては、既に必要な個所でマルチスレッドにしてあります。無駄なスレッドは作っていませんが、通常で7個、最大で同時に10個ほどのスレッドが動きます。 ※音声マルチバッファやそれにまつわるタイマースレッド、フィルタ演算、ファイル出力、独自ファイル形式のバイナリの順序を入れ替えた場合などの、既に作った数百ファイルの自動更新、あるいは解析処理などなど 別の作業やりながら可、ということになるので、起動してから確実に1回は行う必要がある処理が7秒程度で片付ければ、現状でも十分です。(それ以降は数千分の以下とか、大抵のアクションに対しては少ない演算で書き換えて行けるので) >ちなみに昔C++のプロジェクトで40分かかる計算を10秒台まで最適化したことあります。 私はまだまだプログラミングを始めて1年ぐらいだったころなら、何時間かかかった処理を(正確さを多少犠牲にして)5秒程度に出来たこともありましたが このごろだと CPUのクロック数と最小演算量を考えて、おそらく同じハードでは、コードの整合性を保つ限り、さすがにそれほど飛躍的に縮むのは物理的に不可能に思います。 ただし >cl /? >とやれば最適化のオプションがたくさんでてきます。 なるほど そして出てきたコマンドは プロパティ→構成プロパティ→C/C++→コマンドライン→追加のオプション に半角スペース区切りで書きこむことで… っていうことですね? 残念ながらこちらの環境では /arch:SSE3 が使えず、また色々と試してみましたが、今のところコンパイルオプションの変更による、これより大きな改善はみられていません。 (浮動小数をfastにすると0.2秒くらいは縮んだかな?という感じですが、さすがにここはPreciseにしておきたいですし) 64bitコンパイルの実験は、32bitなので出来ず 同じ理由で >Windows7で8GB,16GBなどの場合、スワップファイル(仮想メモリ)を使用しない。 >設定にすれば、なんじゃこりゃ!?と思うほど速くなります。 も試すことができません。 ただ、そのうちWindows7 64bitは手に入れたいので それが叶ったら是非試してみようと思います。 なお、それ以外の構想としては CUDA対応のビデオカードを使い けた外れに多い演算は(画像処理だけじゃなく音声処理の場合だろうが)CUDAからビデオメモリに委託 という手も考えています。 そもそもCPUではなくGPUでドカーンとやってもらおうという作戦です。 (ただし最速パターンだと浮動小数の演算結果が異なるらしいので、その辺は試してみないと) うまくいった場合、CUDAを使うバージョンと 対応できない環境でも使えるようにする、非CUDAバージョンの実行ファイルを両方リリースする(か、それによるパフォーマンスの低下が気にならないレベルなら動的リンクをするかする)可能性が高いですが 聞いた話から判断すると 少なくともこの方法だと うまくいけばCUDA対応版の、その重要な部分は数倍程度速くなる、かもしれません。 まぁそんなこんなですが、とりあえず ありがとうございました♪

  • anpauro11
  • ベストアンサー率28% (4/14)
回答No.2

メモリのキャッシュの使い方じゃないでしょうか? 私が知ってる範囲では、 デバッグビルドではアロケータがメモリに割り当て済みの領域を感知して上書きするのですが、 リソースビルドでは上書きすることなく、新規で領域を割り当てる するとメモリ使用量が上がるので動作が遅くなる・・・ということ?(自信なし) 対策としてはnewで作成したオブジェクトをdeleteでつぶさに削除することに尽きると思います。 上記を一度試してみてください。

LongSecret
質問者

お礼

ありがとうございます♪ >デバッグビルドではアロケータがメモリに割り当て済みの領域を感知して上書きするのですが、 >リソースビルドでは上書きすることなく、新規で領域を割り当てる おや、そうなのですか!? どっちにしても「コード通りの挙動はする」という意味での「バグにはならないような挙動をする」ということですよね? 現状バリバリの完全ネイティブですので ガベージコレクタは動いてないので >対策としてはnewで作成したオブジェクトをdeleteでつぶさに削除することに尽きると思います。 これはかなり正確に(使いまわした方が得策かどうかも考慮に入れたうえで、この場合はこの時点まででdeleteしていいな、こっちはとっといた方が良い、とかも踏まえて)行うことを心がけています。 なお このアプリケーションの機能上 もしも馬鹿正直にメモリを使うと 何百MBとか1GB越えとか平気で行ってしまう という感じになってきてますが 音声や描画のマルチバッファ(多すぎない範囲でビデオメモリも使用)に加え、場合により自作のメモリプールや メモリマップドファイルの有効活用により よほどのことをしない限り どんなにガンガンに使っても 「最大限の計算をしているところ」でも、まずメモリ使用量は(仮想メモリ込みで)100MB以内程度、メモリのみでは20MB以内程度には大抵収まる 通常時ではメモリ使用が8MB以内、仮想メモリ込みでも15MB程度以内にはまず収まっています。 メモリ使用量の推移からみても、リークは確認できた範囲では全て潰していると思われます。 そして音声のマルチバッファ+描画位置を30FPS程度で2か所のウインドウに書き換えしつつ 同じく30FPSで「再生地点を示すライン、及びその背景部分に当たるところ」の再描画 を、DirectXなどのAPIを、こっちのアプリでは今のところ使わずに WindowsAPIのGDIのみで行って タスクマネージャにCPU使用率が0%と表示されてる、というような状態です。 もっと「ここを改良したい」と思うところを改良できる方法を思いついたら、その都度改良しますが かなりの研究と手間をかけたので (そのために、車輪の再発明の必要が生じたりして、開発速度はところどころ遅くなってしまっていましたがw) 現状でも「パフォーマンスに関してはなんでもござれ」というような状態になっていました。 そう、今回の謎が出るまでは(苦笑) しかし、下記の通りの状態となりました。 とてもよかったです。

関連するQ&A

  • デバッグ開始でbin\Releaseにファイルが作成されてしまう。

    デバッグ開始でbin\Releaseにファイルが作成されてしまう。 Visual Studio 2008でC#によるWindowsアプリケーションを作成しているのですが、デバッグ開始を実行するとbin\Releaseにexeファイルなどが作成されてしまいます。 ビルドするとbin\Releaseにexeファイルなどが作成されます。 デバッグ開始の実行でbin\Debugにexeファイルなどが作成され、ビルドするとbin\Releaseに作成されるようにしたいのですが、どうすれば良いですか? ちなみに***.vshost.exeはbin\Releaseに作成されます。 これもbin\Debugに作成されるようにしたいです。

  • リリース版にすると例外エラーが発生する

    同じような質問がないか検索したのですが、ないようなので質問させてもらいます。 Visual C++2010 Expressを使ってプログラムを書いている、アプリケーション作成初心者です。 デバッグが一区切りしたため、リリース版でビルドし実行したところ、コンストラクターの 内部で、下記のエラーが発生しました。 ”アプリケーションのコンポーネントで、ハンドルされていない例外が発生しました。” ”使用されたパラメータが有効ではありません” デバッグ版では、発生しません。 エラーが発生するコードは、以下の行です。 InitializeComponent(); Blank = gcnew Bitmap("Blank.png"); この、Bitmapをgcnewする行で、上記のエラーウィンドウが表示されます。 ビルドパラメータは、リンカ入力の追加の依存ファイルに"Wsock32.lib"が指定されています。 他は、変更していません。 メモリの問題でしょうか? よろしくお願い致します。

  • VS2005 リリースビルドしたEXEが他のPCで開けない

    VS2005 C++ ExpressでWindowsフォームアプリケーションをC++/CLIで作成しています。 (Standardを買う予定なのですが、まだ買いにいけていないのでExpressのままです) OSはWinXP Pro-SP2です。 リリースビルドしたexeファイルを、当該PCでは実行可能なのですが、 exeを他のPCにコピーして実行すると、 「このアプリケーションの構成が正しくないため、アプリケーションを開始できませんでした。アプリケーションを再度インストールすることにより問題が解決する場合があります」 というダイアログが表示され、終了してしまいます。 検索してみたところ、いくつか対処法があったのですが、試した中では解決できませんでした。 ◎ソリューションのプロパで、[構成プロパティ]-[C/C++]-[コード生成]で、ランタイムライブラリを「マルチスレッドDLL/MD」を「マルチスレッド/MT」に変更    →ビルド時に「/MTと/clr:pureは同時に使用できません」エラー    →/clr:pureを/clrのみにしても同じ。    →「共通言語ランタイムサポートを使用しない」にすると、      「マネージターゲットコードには/clrが必要」でビルドエラー    →→→/MD /clr:pureに戻しました ◎exeと同じディレクトリにmanifestを作成      ▽ファイル名はMicrosoft.VC80.CRT.manifest <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.762" processorArchitecture="x86" > </assemblyIdentity> <file name="msvcr80.dll"/> </assembly> versionについては、VC++Expのバージョン情報で表示されるものに変更。    →同じように、exe実行時にエラー発生、同じダイアログ    →msvcr80.dllを同じディレクトリに置いても同じ ◎Platform SDKのDependency Walkerでexeをチェック    →MSJAVA.DLLが見つからないという赤いメッセージが出る。    →ファイル名をPC内で検索したが、見つからず。      (VS2005ExpがインストールされたPCも、別のXPが入ったPCも)    →試しに、vectorで拾った実行OKなDLL不要exeアプリをD-Walkerに      かけてみたら、同じようにMSJAVA.DLLが見つからないという      メッセージが表示された。 でも当然このexeはどのPCでも実行OK。 ◎新しくプロジェクトを作成。 ボタンをひとつ配置し、  イベント発生の関数のみ作成。 ただし中身はカラ。 private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { }    →デバッグビルドもリリースビルドも問題なし。 でもexeを      別のPCにコピーすると同じダイアログが出てエラー終了 ◎http://support.microsoft.com/kb/814496/jaに載っている方法:   Visual Studio .NET プロジェクトで app.config ファイルの <xml> を   UTF-8 に変更し、UTF-8 エンコードで app.config ファイルを保存します。    →app.configファイルが検索しても見つからず これは何が悪いのでしょうか? ライブラリ・ランタイム関連であろうということはわかるのですが、 解決方法がわかりません。 よろしくお願いします。

  • Sygate5.6 ビルド2808 を使用していますが

    Sygate5.6 ビルド2808 を使用していますが 『 アプリケーション NT Kernel & System ファイル名(ntoskrnl.exe)のネットワークへの接続がブロックされました 』といった表示だけが頻繁に出てきます。PCに全く触れていない状態でも表示がでます。 設定を再度確認してみても変わりません。 どうすれば出なくできますか? よろしくお願いいたします。 Windows Xp Home SP2です。

  • Visual Studio.NET2003でビルドの中止

    ソリューションファイルに 大量のプロジェクトがある場合 一度ビルドしてしまうと途中で する方法を探しています。 ビルド中にスタートアッププロジェクトの設定や Debug/Releaseを変更すると中止するかどうか 聞いてくるウインドウが出るのですが 何かキーを押せば中止出来るなどの機能は ないのでしょうか?

  • リビルド後に実行しようとするとビルド要求のメッセージが出る

    VC++6.0のMFCを使って開発しているアプリケーションがあります。そのアプリケーションをビルドする際に起きる問題についてです。 リビルドした後に実行ファイルを実行しようとすると「ビルドしますか?」というメッセージが出てきます。リビルドしたばかりなのに何故ビルドが必要なのかわかりません。それから、再ビルド時には全ソースファイルがコンパイルされているようですので、実行されるまで時間がかかってしまいます。 リビルドしたときにはコンパイルエラーや警告はありませんし、リビルド後には確かに実行ファイルは生成されています。「ビルドしますか?」のメッセージが出ても「はい」ボタンをクリックしてビルドが完了すれば実行ファイルが実行されます。この問題は開発当初からあった問題ではなく、あるときから突然起きた問題です。いつから起きた問題なのかはわかりません。ちなみに、この問題は「バッチビルド」を使って複数のコンフィグレーションをリビルドした時に起きるようです。1つのコンフィグレーション(実行したいコンフィグレーション)のみをリビルドした後にはこの問題は起きません。また、リリース版、デバッグ版ともにこの問題は起きます。 下記はメッセージの内容です。(英語版のVCなのでメッセージは英語です。) (xxxは実行ファイル名、aaa、bbb、cccはソースファイル名) ---------------------------------------------------- One or more files are out of date or do not exist. These files need to be build: .\Debug\xxx.bsc .\Debug\xxx.exe .\Debug\aaa.obj .\Debug\bbb.obj .\Debug\ccc.obj <more file ...> Would you like to build them? ---------------------------------------------------- 原因や解決方法をご存知の方、ご教授をお願い致します。 環境:Win2000(日本語版)、VC++6.0(英語版)、MFC

  • Windows EXEファイルのリリースについて

    Visual studio(C#)でコンパイルした、 Windows EXE実行ファイルのリリースについて質問です。 バッチシステムとしてタスクスケジューラーで起動させますが、 頻繁にシステム改修があり、都度リリースが必要です。 しかし、システム実行中にリリース(EXEファイルの上書き)を行うと、 起動中のため上書きエラーとなります。 実行中のEXEに対して、 次回の実行分から最新のシステム改修を反映させるには、 どのようにしたら良いでしょうか? 以下私の案がございますが、スマートではありませんし、 実行開始に時間がかかるデメリットがございます。 他にスマートな案はございますでしょうか? 起動に関するフレームワークなどあるのでしょうか。 <案> 1.処理開始時に本体EXEファイルをコピーして実行版EXEファイルを作成する(同一のEXEファイル) 2.実行版EXEファイルを起動する 3.実行中でも本体EXEファイルは上書き可能なため、本体EXEファイルに対してリリース(EXEファイルの上書き)を行う

  • Relaeaeモードでビルドできない。

    こんにちは。皆様に教えて頂きたいのですが、いまDebugモードでビルドできているのですが、Releaseモードで同様にやると、「fatal error C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました」と出ます。そこで、 関係するsourceの*.cのヘッダーに#include "stdafx.h"を加えたところ、「fatal error C1853: 'Release/***.pch' プリコンパイルされたヘッダー ファイルは、このバージョンのコンパイラと互換性がありません。」とエラーが出ます。どこが間違っているのかお分かりの方教えて頂けませんでしょうか?よろしくお願いいたします。

  • C#のビルド方法について質問です。

    IDEをつかわず、コマンドプロンプト上でC#のソースをビルドする時の方法について質問です。 まず以下のようなコードがあるとします。 まずC:\の直下に以下のソースを作成しました。 =================================================== using System; using System.IO; using System.Windows.Forms; namespace Add.TestClass{ public class LibraryClass{ public LibraryClass(){ MessageBox.Show("クラスライブラリコンストラクタの実行"); } } } =================================================== 上記クラスをdllファイルとしてビルドします。 csc /t:library /out:Add.TestClass library.class  と上記のようにビルドしました。するとAdd.TestClass.dllというファイルが確かにできあがりました。 次にこれを実際に実行するためのファイルをつくりました。 それが以下になります。 同じくC:\直下に以下のようなソースを作成します。 =================================================== using System; using System.IO; using System.Windows.Forms; using Add.TestClass; public class MainClass{ public static void Main(String [] args){ LibraryClass obj = new LibraryClass(); } } =================================================== このファイルをビルドします。 csc /r:Add.TestClass.dll main.cs としてビルドし、その後 mainというファイルを実行しました。 するとキチンとMessageBoxで MessageBox.Show("クラスライブラリコンストラクタの実行");が実行されました。 ここまでは問題ないのですが、この場合 main.exeファイルとAdd.TestClass.dllというファイルが 同じ階層に存在するような状態になっているのですが、これを main.exeファイルのある階層にdllというディレクトリを作成し そのdllの中にAdd.TestClass.dllというファイルをおいた階層状況でmain.exeファイルを実行したいのです。 そのためにまず、 csc /r:”C:\dll\Add.TestClass.dll" main.cs 上記のようなビルドオプションでビルドしてみたのですが、ビルドはとおりましたが -------------------------------------------------------------------------------------------------------------------- ハンドルされていない例外: System.IO.FileNotFoundException: ファイルまたはアセン ブリ 'Add.TestClass, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'、ま たはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりませ ん。 場所 MainClass.Main(String[] args) -------------------------------------------------------------------------------------------------------------------- というエラーがでました。 このdllファイルを特定の任意のディレクトリ内において、main.exeを実行してうまく動くようにするためには どのようなビルドオプションをつけたらいいのでしょうか? よろしくご教授お願いいたしま。

  • UbuntuのQtでビルドして配布する方法について

    Qtでビルドして他のUbuntuマシンで実行する方法を教えてください。 UbuntuにQtをインストールしてプログラムを作成しております。 ビルドして開発に使っているマシンで実行ファイルをダブルクリックすると動きますが、他のUbuntuマシンに実行ファイルをコピーしてダブルクリックすると 「実行するためのアプリケーションが見つかりません」 という感じのメッセージが出ます。 「実行するためのプログラムを探してインストールする」 を選択すると、「PyPar2」がインストールされますが、実行すると「PyPar2」のウインドウが出て、「実行」を選択してもプログラムは実行されません。 ビルドはQtのメニューバーから「ビルド」-「すべてリビルド」を選択しております。 実行ファイル以外に配布するファイルがあるのか、ビルド方法が間違えているのか、ランタイムのようなものが必要なのか、実行ファイルだと思っているファイルが実は違うのではないか、など自分で調べてみましたが、分かりませんでした。 初歩的な質問で申し訳ありませんが、お分かりの方が居られましたら、ご教授をお願いいたします。 よろしくお願いいたします。

専門家に質問してみよう