3

過去数か月間、私はVisual C ++プロジェクトに取り組んでおり、カメラから画像を取得して処理しています。今日まで、これはデータを更新するのに約65ミリ秒かかりましたが、今では突然大幅に増加しています。プログラムを起動すると、最初の30回ほどの反復で期待どおりに実行され、その後、ループ時間が65ミリ秒から250ミリ秒に突然増加します。

奇妙なことに、各関数のタイミングを計った後、速度低下を引き起こしているコードの部分はかなり基本的であり、1か月以上変更されていないことがわかりました。そこに入るデータは変更されず、反復ごとに同一ですが、最初は1ミリ秒未満だった実行時間は、残りのコードが期待どおりに(時間的に)実行されている間に突然170ミリ秒に増加します。

基本的に、私は同じ関数を何度も呼び出しています。最初の30回の呼び出しでは、正常に実行され、その後は明らかな理由もなく速度が低下します。また、これは実行時間の突然の変化であり、段階的な増加ではないことにも注意してください。

これを引き起こしている可能性がありますか?コードは一部のメモリ(〜50 kb / s)をリークしていますが、突然の4倍の速度低下を保証するには十分ではありません。誰かアイデアがあれば聞いてみたいです!

編集:うわー、それは速かった!これが速度を落とすコード(いくつかの数学を除いたもの)です。これは、行数を増やすと計算時間が急激に増える関数だと思います。ここで重要なのは、同じデータを使用すると、30回の反復後に速度が低下することです。

void CameraManager::IntersectLines()
{

    // Two custom classes
    TMaths maths;
    TLine line1, line2;

    while(lines.size()>0)
    {

        // Save the current line
        line1 = lines[0];

        // Then remove it from the list
        lines.erase(lines.begin());

        CvMat* aPoint;
        for (int i = 0; i<lines.size(); i++)
        {

            line2 = lines[i];

            aPoint = cvCreateMat(1, 4, CV_32FC1);

            // Calculate the point of intersection
            maths.Intersect(line1.xyz, line2.xyz, line1.uvw, line2.uvw, aPoint);

            // Add the point to the list
            points.push_back(aPoint);
            }

        }

    }

}

4

7 に答える 7

9

一定量のメモリをリークした後、コンピューターがページイン/アウトを開始する必要がある可能性はありますか? それは間違いなく単純な機能でさえ遅くなります。

関数が何をするのかを知らなければ、何が問題を引き起こしているのかを正確に判断することは困難です。

編集: 質問のコメントで示唆されているように、一定量のメモリをリークすると、CPU キャッシュから何かがノックアウトされ、速度が低下する可能性もあります。メモリ リークを修正するか、ここにコードを投稿して確認することをお勧めします。

編集 2: そのループでいくつかの関数を呼び出します。彼らは単純な算術計算以外に何かをしていますか?

于 2010-06-15T18:27:42.270 に答える
5

ページをいっぱいにするのに十分なメモリ リークが発生した場合 (50KB/秒で十分な場合があります)、Windows はページを切り替えてデータを処理する必要があります。これが起こると、プログラムは非常に非効率になります。

于 2010-06-15T18:28:47.807 に答える
2

メモリリークが発生した場合は、コードに何か問題が発生していることは間違いありません。最初にそれを修正すると、問題を発見するか、少なくとも1人のかなり明白な容疑者を排除する可能性があります。

他の人が言っているように、あなたがいくつかのコードを提供した場合、あなたを助けようとするのははるかに簡単でしょう...

[編集]cvCreateMatあなたの関数はメモリを割り当てている と思いますか?それはどこかで解放されることはありますか?

于 2010-06-15T18:35:51.613 に答える
2

明らかに何かが変わった。コードをスローダウン前の状態に戻してみてください。その後再び高速になった場合は、コードの変更に注目してください。遅い場合は、コードの外部で問題を探します。データベースやOSなど。

于 2010-06-15T18:31:25.693 に答える
1

コードをプロファイリングすると、答えを推測する必要がなくなります。

もちろん、これはとにかくコードのパフォーマンスを変更する可能性がありますが、コードで何が起こっているかを正確に確認する最も直接的な方法です...

(この質問に対する現在のトップの回答: Visual Studio 2008 PRO でのプロファイリングによると、組み込みのプロファイラーを使用するには VS 2008 の「チーム」エディションが必要です。それ以外の場合は、外部プロファイラーを使用する必要があります)

于 2010-06-15T19:48:56.057 に答える
1

コンテナー内の各行を消去する必要がありますか?

    // Then remove it from the list
    lines.erase(lines.begin());

コンテナーによっては、特に大きなコンテナーの場合、要素の消去 (一度に 1 つずつ) が遅くなる場合があります。計算中に開始インデックスを使用することをお勧めします。関数を呼び出す前にインデックスを進めます。インデックスと反復子は、要素を消去するよりも更新が高速です。計算後、コンテナー全体を削除または消去できます (clearコンテナーにコンテナーがある場合は、メソッドを参照してください)。このclear方法は、一度に 1 つの要素を消去するよりも高速な場合があります。

于 2010-06-15T19:06:14.800 に答える
0

有用な回答が必要な場合は、質問をより具体的にする必要があります。

于 2010-06-15T18:29:04.807 に答える