1

募集: アプリ (およびその結果としてシステム全体) の速度が低下する原因となっている CPU 使用率を軽減するためのヒントやコツ。

アプリがあります。複数のスレッドを呼び出します。たぶん5人くらい(現時点での推測)。シリアル ポート スレッドは絶対に必要です。私は、そのスレッドが責任を持って動作していることをかなり確信しています (たとえば、すべてのバイトが想定どおりにそこに到達するなど)。

バックグラウンドのシリアルポートハンドラーの結果を監視し、ルーチンなどで発生するセマフォに応答するスレッドが他にもいくつかあるbutton1_clickので、全員がうまくやって全体がスムーズに実行されます。基本的に、それらはセマフォをチェックし、値がそうであれば分岐する大きな while ループです。

最近、20 の個別のスレッドを追加しました。他のものから分離します。これらのスレッドは、20 個の長方形に点と線を配置します (問題のデバイスには 20 チャネルがあります)。私のアプリはそれらを記録してグラフ化するために存在します。

これらのスレッドを追加した結果、アプリはすぐに非常に遅くなりました。実際、マシン全体が非常に遅くなりました。

だから私はアプリを止めました。マシンはまだ遅かった。そこで、Visual Studio を終了しました。まだ遅い。

二次的な症状: コンピュータ自体のファンが速度を上げました。その後、再び速度を上げました。そしておそらく3回目。電源ファンだったと思います。しかし、それはファンであり、速度を上げ続けました。タスクマネージャーは私にこれを見せました...

タスク マネージャーのパフォーマンス [プロセス] タブでは、大きな豚が...

myApp.vshost.exe

そのプロセスの彼の「説明」は...

vshost32.exe

タスクマネージャーを使用してプロセスを終了しました。

ちなみに、これはアプリではなく、そのような名前のアプリがApplicationsタブにリストされていませんでした。Processesタブだけ見ました。

プロセス終了後myApp.vshost32.exe、CPU 使用率は元に戻りました。

vshost32.exe 終了後のタスク マネージャー CPU 使用率のほぼ垂直方向の増加はすべて、20 個の新しいスレッドを開始する行為と高度に相関していました。(ボタンをクリックするとスレッドが開始されます。ワンクリック、ザップ、CPU 100 です。) ほぼゼロに戻ることは、終了する行為と完全に相関しているvshost32.exeので、(少なくとも現時点では) それvshost32.exeが原因であると確信しています。

このセクションを追加したときに問題が発生しました...

       //
       //
       //  Do a bunch of stuff to set up the 20 graphs; had no problem
       // 
       // 

        for (int i = 0; i < 20; i++)
        {                                   // Start each thread
             our20Graphs[i].Begin();        // Start my problems
        }                                   // Entire machine now goes 2 MPH

独自のクラス内の独自のファイル内の実際の犯人はここにあります...

    this.th = new Thread(new ThreadStart(RunTarget));

    //
    //
    // lots of other stuff
    //
    //
    //

    public void Begin()                             ///// A method in the Runtarget 
    {
        this.th.Start();
        this.th.IsBackground = true;
    }

私のタスクに似た他のアプリを見たことがあります。これらのアプリは、非常に類似した一連のグラフを積極的にリアルタイムで作成し、極端な CPU 使用率に近づくことなく、はるかに高速です。

現在、私のグラフ作成ルーチンは非常に時間がかかっているため、データが画面にまったく表示されません。何が起こっているのかわかりません。

それが十分に悪くなかった場合 (そして、それは十分に悪いよりも悪いです、それはショー ストッパーです) これにより、私のアプリがプリマドンナ アプリよりも悪い点までマシン全体が遅くなり、まったく使用できなくなります (機械は基本的に低温で停止します)。

では、なぜ 20 個のスレッドがシステムをひどく過負荷にするのでしょうか?

他のスレッドが自分の仕事をする機会を得るために、意図的に各スレッドを少しの間スリープ状態にすることになっていますか?

すべての最大の問題:myApp.vshost.exeアプリを終了して Visual Studio を終了した後も (99% の CPU ホグとして) 実行し続けたのはなぜですか?

非常に多くの CPU 時間を浪費しているものを排除するために私ができることについての提案を歓迎します。

(編集を追加、コミュニティのアドバイスで、これは RunTarget です)

    private void RunTarget()
    {
        while (proceed)
        {
            if (!finished)
            {
                if (!pause)
                {
                    this.screenReady = false;
                    g.Clear(Color.Black);

                    //   bg.DrawRectangle(new Pen(Brushes.Aqua, 3), new Rectangle(0, 0, 1024, 40));
                    //  oldG.DrawRectangle(new Pen(Brushes.Red, 3), new Rectangle(0, 0, 1024, 40));

                    if (v_surface)
                    {
                        g.DrawImage(beginSurface, new Point(ImagePlace - area.Width, 0));

                        g.DrawImage(OldSurface, new Point(ImagePlace + 1, 0));

                        // g.DrawString(ArrayPlacement.ToString(),new Font("Arial",18),Brushes.Blue,new PointF(20,20));
                    }
                    else
                    {

                        g.DrawImage(OldSurface, new Point(ImagePlace - area.Width, 0));

                        g.DrawImage(beginSurface, new Point(ImagePlace + 1, 0));

                    }

                    this.screenReady = true;

                    if (ImagePlace % 64 == 0)               //// 64 is the size of the array of ints
                    {
                        finished = true;
                    }

                    if (ImagePlace == area.Width)
                    {
                        ImagePlace = 0;

                        if (v_surface)
                        {
                            v_surface = false;
                        }
                        else
                        {
                            v_surface = true;
                        }
                    }
                    else
                    {
                        ImagePlace += 32;               //// This is the scrolling increment
                    }

                    Draw();                             //// This physically puts it on the screen
                }
            }
        }
    }                                                   //// End of private void RunTarget()
4

3 に答える 3

1

ここにはいくつかの問題があると思います。最初は、他の人が述べたように、描画スレッドは本質的に無限ループであり、スレッドごとに単一コアの 100% の CPU 時間を使用する「ビジー待機」によってデータを一時停止しているように見えます。これに、使用している 20 スレッドを掛けると、システムが 20 個の CPU コアを完全に占有するのに十分な作業をシステムに与えることになります。これは、システムが持っているよりもはるかに多いため、システム上の他のスレッドが不足し、マシンの速度が低下します。

これが応答するように注文します。何らかの待機メカニズムを使用して、データ ポイントの一時停止を再実装する必要があります。Thread.Sleep はそのような手段の 1 つですが、描画にジッターが発生する可能性があります。代わりに、現在の実装のようにビジー状態で待機するのではなく、使用可能なデータがない場合に、コンシューマ スレッドが (CPU 時間を使用せずに) 待機できるようにする、BlockingCollection などのある種のブロッキング キューを使用します。

もう 1 つの問題は、描画は常にメイン スレッドで行われる必要があり、バックグラウンド スレッドで描画アクティビティを実行すると、他の問題が発生する可能性が高いことです。

于 2013-01-16T18:16:18.353 に答える
1

ここに画像の説明を入力

プロジェクト プロパティから Visual Studio ホスティング プロセスを無効にしてみてください。プロジェクトのプロパティ --> デバッグ --> デバッガーを有効にする にあります。

于 2013-01-15T21:00:01.697 に答える