2

このコードでi7プロセッサーの使用率を100%にするにはどうすればよいですか?XmlDocumentで何か特別なことが起こりますか?コンテキストの変更だけが原因ですか?もしそうなら、なぜもっと多くのスレッドを配置してもプロセッサがそのフルパワーを使用しないのでしょうか?一度に複数の文字列を解析するための最も簡単な方法は何でしょうか?

編集:

おそらく、このコードは、プロセッサの30%を使用するスレッドの数に関係なく、より明確になります。

    private void Form1_Load(object sender, EventArgs e)
    {
        Action action = () =>
        {
            while (true)
            {
                XmlDocument xmlDocument = new XmlDocument();

                xmlDocument.LoadXml("<html><body><div>1111</div><div>222</div></body></html>");
                var nodes = xmlDocument.SelectNodes("//div");
            }
        };

        Parallel.For(0, 16, i => action());
    }
4

4 に答える 4

3

あなたのコード サンプル (プロファイラーでこれを見ることができます) では、それらのスレッドを実行するために利用可能なリソースを待つのに多くの時間を浪費しています。常により多くのリクエストを行っているためParallel.For(これはノンブロッキング コールです)、プロセスは、スレッドが終了し、次のスレッドが選択されるのを待つのにかなりの時間を費やしています (すべての実行時間をリクエストするスレッドの量が増え続けています)。 )。

プロファイラーからの次の出力を検討してください。

赤はシンクロ!私のアプリが非常に多くのスレッドを実行できるようにするために、カーネルがどれだけの作業を行っているかを見てください! シングル コア プロセッサを使用している場合は、間違いなく 100% と表示されることに注意してください。

ここに画像の説明を入力

文字列を分割して個別に解析することで、この xml を読むのに最適な時間を過ごすことができます (もちろん、I/O からのロード後)。100% の CPU 使用率が表示されない場合がありますが、これが最適なオプションです。文字列のさまざまなパーティション サイズ (つまり、部分文字列のサイズ) で遊んでください。

並列パターンに関するすばらしい読み物として、Stephen Toub による次の論文をお勧めします。

編集複数のスレッドでxmlを読み取るスマートな方法をいくつか検索しました。私の最善のアドバイスはこれです:

  1. 可能であれば、xml ファイルを小さなファイルに分割します。
  2. xml ファイルごとに 1 つのスレッドを使用します。
  3. パフォーマンスのニーズに対して 1&2 では不十分な場合は、xml として完全にロードするのではなく、文字列を分割 (分割) し、手動で (XmlDocument ではなく) 少し解析することを検討してください。これは、1 と 2 で十分な場合にのみ行います。各パーティション (部分文字列) は、独自のスレッドで実行されます。「より多くのスレッド」 != 「より多くの CPU 使用率」も覚えておいてください。少なくとも、あなたのアプリではそうではありません。プロファイラーの例でわかるように、スレッドが多すぎるとオーバーヘッドが大きくなります。複雑にしないでおく。
于 2012-05-02T21:16:02.210 に答える
3

これは実行している実際のコードですか、それともファイルまたは他の URL から xml をロードしていますか? これが実際のコードである場合、おそらく終了が速すぎて、CLR がスレッド数を最適化する時間がありませんが、無限ループを配置すると、CPU を最大限に活用することが保証されます。

実際のソースから XML をロードしている場合、スレッドは IO 応答を待っている可能性があり、その間は CPU を消費しません。そのケースを高速化するには、多数のスレッド (20 以上など) を使用してすべての XML をメモリにプリロードし、後で 8 つのスレッドを使用して XML 解析を行うことができます。

于 2012-05-02T20:58:41.573 に答える
0

プロセッサは、最新の PC で最速のコンポーネントです。ボトルネックは、多くの場合、RAM またはハード ドライブの形で発生します。最初のケースでは、大量のメモリを消費する可能性のある変数を継続的に作成しています。したがって、キャッシュがすぐに枯渇するため、RAM がボトルネックになることは直感的です。

2 番目のケースでは、変数を作成していません (高度に最適化された方法ではありますが、.NET はバックグラウンドで多くのことを行っていると確信しています)。したがって、すべての作業が CPU にとどまるのは直感的です。

OS がメモリや割り込みなどを処理する方法を完全に定義することは不可能です。これらの状況を定義するのに役立つツールを使用できますが、前回確認したときは、.NET コード用のメモリ アナライザーすらありませんでした。だから私は答えを一粒の塩で取ると言います。

于 2012-05-02T21:08:51.137 に答える
0

Task Parallel Library はアクションを配布するため、プロセスの使用率に関しては少し制御できなくなります。ほとんどの場合、スレッドの作成が多すぎたり、スレッドが大きくなりすぎたりすることを心配する必要がないため、これは良いことです。スレッドを明示的に作成する場合は、次のコードでプロセッサを最大にプッシュする必要があります。

Parallel.For(0, 16, index => new Thread(() =>
                {
                    while (true)
                        new Thread(() =>
                            {
                                XmlDocument xmlDocument = new XmlDocument();
                                xmlDocument.LoadXml("<html><body><div>1111</div><div>222</div></body></html>");
                                var nodes = xmlDocument.SelectNodes("//div");
                            }).Start();
                }).Start());

このアプローチを推奨すると言っているのではなく、プロセッサを最大限に活用するコードの実例 (AMD FX-6200) を示しているだけです。タスク並列ライブラリも約 30% 使用されていました。

于 2013-03-25T03:59:45.003 に答える