2011-01-20 3 views
7

「削除」機能の実行が遅いC++アプリケーションがあります。これを引き起こす原因は何か、ソリューションの検索はどこから始めるべきですか?C++の「削除」が遅いです。どこを最初に見たらいいですか?

背景:

このC++のコードでは、基本的にはDLLでのAutoCADの内部で実行されているARXファイル、です。

削除が遅い特定のコンピュータは、AutoCAD 2011、Windows 7、64ビットを実行しています。 AutoCAD 2011のARXは、Visual Studio 2008 Service Pack 1を使用してコンパイルする必要があります。

問題のあるコンピュータはお客様のコンピュータです。そこにはVisual Studioのどのバージョンもインストールされていません。私の開発コンピュータで

、コードをテストするためのAutoCAD 2011

で問題ありません、私はリンクリストを削除し、いくつかのコードを持っています。問題のあるコンピュータでは、リストを削除するのに0.7秒かかります。問題のないコンピュータと構成では、同じコードに0.02秒かかります。特定の時間は重要ではありません - 2つの数字の間に大きな違いがあります。

両方のコンピュータで同じバージョンのコードを実行していることを確認したので、リリース対デバッグのビルドの問題ではありません。

+1

リストに登録されたアイテムの数はいくつですか?そのサイズは何ですか? –

+2

ベンチマークに使用しているテストコードを共有します。 – karlphillip

+0

両方のシステムで静的/動的にリンクしていますか?デバッグ/リリースビルドを比較していないことを確認してください。 –

答えて

5

大雑把ために、私はそれらをチェックしたい:

  • 他のプラグイン:は、その行動が他のARXファイルによって引き起こされるだろうか?彼らは悪いシステムで無効にすることができますか?
  • PerfMon:削除中にソフト/ハードページフォールトまたはキャッシュミスがピークに達していないかどうかを確認します(お客様のコンピュータでこれを設定してください)。
  • HeapQueryInformation:良い/悪い環境で同じ値ですか?
  • ヒープロック:ヒープのロックをしっかりと保持している他のスレッドがバックグラウンドで非常にアクティブになることはありますか?あなたは、HeapLock/HeapUnlock(もちろん、ロック内の時間)にループをラップすることでテストすることができます。
  • フック:それぞれのコードをフックできますか? (例えば、C++/Win32 Heapに接続してサードパーティ製のアプリケーションを実行して何をしたいかを決める機能)
  • ストローで掴む:それぞれnewは異常に長いですか?個々のdelete時間はどのように分配されますか?
1

作業中/失敗中のシステム間でキャッシュの効率が異なることが原因である可能性があります。障害の発生したシステム上では、大量の削除によってキャッシュをスラッシュさせるメモリ断片化がさらに発生する可能性があります。休止状態のシステムでは、データがより連続的になり、大きな削除中にキャッシュヒットが増える可能性があります。

インテルパフォーマンスカウンタモニタをお試しください。

1

許容され、可能であれば、お客様のコンピュータでプロファイラを使用してみてください。

AMD CodeAnalystまたはインテルプロファイラ(無料ではありませんが)を試すことができます。

これが不可能な場合は、リリースビルドにプロファイリングコードを追加し、顧客から結果を収集します。シンプルなプロファイリングコードでも、実際のボトルネックを見つけるのに役立ちます。

削除自体は問題ではないようですが、問題はコードの他の部分である可能性があります。

など。 - head->resval.rstringのタイプは何ですか?

0

私たちは常にこの問題にぶつかります。あなたのコードで何も問題はありません。何千ものアイテムを削除するには、リリースモードでも数秒かかることがあります。

答えは削除されません。実際のメモリアロケータを取得し、各オブジェクトを個別に割り当てる代わりに、メモリプール(またはカスタムヒープなど)を作成します。 Nedmallocを使用してお勧めします。あなたは "ネッドプール"を作成できます。基本的に、プールはオブジェクトが割り当てられるメモリブロックです。各オブジェクトにはまだメモリが割り当てられますが、OSから直接ではなくプールから取得されます。

削除する時間が来ると、オブジェクトを1つずつ削除するのではなく、プール全体を削除するだけです。同時に期限切れになるオブジェクトのバッチごとに異なるプールを使用します。プール全体のメモリを割り当てる必要はありませんが、一度にすべてを削除することしかできません。

+0

これを行うと、ほとんどのC++オブジェクトは未定義の動作をします。少なくとも呼び出されるオブジェクトのデストラクタを手配する必要があります。 –

+0

もちろん。インプレースを新しく使用し、手動でデストラクタを呼び出す必要がありますが、メモリの割り当てを解除しないでください。 –

0

どのようにしてリトリストが生成されますか?さらに、acutNewRbとacutRelRbを使用する代わりに手動でresbufsを割り当てたり削除したりする理由はありますか?

また、これらをチェックしたことがありますが、AutoCAD 2009と2011の両方でデフォルトの図面が読み込まれていますか?そうでない場合、図面は同じですか(ACADバージョンを除く)、ローカルに配置されているのか、ネットワークドライブに配置されていますか?また、両方のインスタンスで同じlisp/.Net/objectARXアプリケーションが実行されているかどうかを調べることもできます。また、AutoCAD 2011はネットワークまたはローカルインストールですか?

最後に、autocadタグとobjectarxタグを質問に追加することもできます。

+0

acutBuildListを使用してretListが生成されています。私はメモリを解放するためにacutRelRbを使用していましたが、コードをプロファイリングする際に、その機能が問題であることがわかりました。私は、それが問題を解決するかどうかを確認するために手動で書き直しました(問題ありませんでした)。すべてのケースで同じコードでコードを実行しています。 –

関連する問題