0

さまざまなサードパーティ API を呼び出してデータを収集する必要があるコンソール アプリケーション (c#) があります。これは、異なるユーザーに対して同時に行う必要があります。そのためにスレッドを使用しています。しかし、ユーザー数が増加するにつれ、このサービスは CPU パフォーマンスを圧迫しています。他のプロセスに影響を与えています。並列処理にスレッドを使用できるが、CPU パフォーマンスに大きな影響を与えない方法はありますか?

4

2 に答える 2

1

あなたの質問から、スレッドを手動で作成していると思います。これに答える簡単な方法は、Task Parallel Libraryのような API を使用することを提案することです。それらを処理するためのスレッドの数 - したがって、500 の API リクエストが与えられた場合、数スレッドに制限されます。

ただし、より詳細に答えると、この問題が発生する一般的な理由は、コードが作成するスレッドが多すぎることです。スレッドは無料のリソースではなく、高価です。

あなたの質問に基づいて作成された例は次のとおりです。

  • 呼び出す必要がある 5 つのサードパーティ API があり、それぞれがユーザーごとに最大 1 MB のデータを返します
  • ユーザーごとに、個別のバックグラウンド スレッドで各 API を呼び出します。
  • 100 人のユーザーがいます
  • したがって、合計で 500 のスレッドが作成され、それぞれがネットワークからのデータを待機しています。

ここでの問題は、プログラムが管理しようとしているスレッドが 500 あり、それらはすべてシステムの最も遅い部分であるネットワークで待機していることです。

もっと簡単に言えば、一度に 1 つずつダウンロードするのではなく、一度に 500 個のデータをダウンロードしようとしています (この例では、すべてがゆっくりと終了することを意味します)。各スレッドは何もしない (ネットワークを待機するだけ) ため、CPU はアイドル状態のスレッドを継続的に切り替えます。ユーザー数を増やすと、スレッドの数が増えます。これにより、実際には各スレッドのダウンロードが遅くなりますが、スレッド間の切り替えのためだけに CPU 使用率が増加します。これが (おおよそ) ユーザー数が増えるにつれてパフォーマンスが低下する理由です。

より良い例は、同じシナリオを採用し、バックグラウンド スレッドを 1 つだけ使用することです。

  • 呼び出す必要がある 5 つのサードパーティ API があり、それぞれがユーザーごとに最大 1 MB のデータを返します
  • 各 API 呼び出しはキューに入れられ、キューは単一のスレッドによって処理されます
  • 100 人のユーザーがいます
  • したがって、バックグラウンドで実行されている 1 つのスレッドがあり、各リクエストに対してネットワークの利用可能な帯域幅をすべて使用しています。

この例では、CPU 使用率はほぼ一定です。ユーザーの数に関係なく、実行中のバックグラウンド スレッドは 1 つだけなので、コンテキストの切り替えは最小限に抑えられます。個々の API 呼び出しは、ネットワーク カードの最大レートで実行されるため、できるだけ早く終了します。

現実には、おそらく 1 つのスレッドでは十分ではありません。別の場所に制限要因があるため、1 つの要求でネットワークが飽和状態になることはほとんどありません。ただし、これは後で調整できるものです。おそらく 2 つまたは 3 つのスレッドの方がパフォーマンスは高くなりますが、4 つのスレッドではさらに遅くなります。スレッド化の一般的なルールは、作品ごとにスレッドを作成するのではなく、小さく始めて作業を進めることです。

于 2013-10-31T14:57:24.520 に答える
0

まず、プロファイラーを実行し、いくつかのリファクタリングツールをチェックアウトして、コードの最適化を実行して問題を解決できるかどうかを確認します。アプリケーションがまだサーバーに過負荷をかけている場合は、負荷分散をセットアップするか購入してください。それまでの間、最新の OS を実行している場合は、ハッキーなCPU レート制限を設定してみてください。

于 2013-10-31T14:54:29.047 に答える