1

さまざまな数の許可されたスレッドで実行されているマルチスレッド プログラムをプロファイリングしています。以下は、同じ入力作業を 3 回実行したときのパフォーマンス結果です。

1 thread:
  Total thread time: 60 minutes.
  Total wall clock time: 60 minutes.

10 threads:
  Total thread time: 80 minutes. (Worked 33% longer)
  Total wall clock time: 18 minutes.  3.3 times speed up

20 threads
  Total thread time: 120 minutes. (Worked 100% longer)
  Total wall clock time: 12 minutes.  5 times speed up

同じ作業を行うのにより多くのスレッド時間がかかるため、スレッドがリソースをめぐって競合しているに違いないと感じています。

アプリ マシンとデータベース サーバーの両方で、4 つの柱 (CPU、メモリ、diskIO、ネットワーク) を既に調べました。メモリは元の競合リソースでしたが、現在は修正されています (常に 1G 以上の空き容量があります)。CPU は、20 スレッドのテストで 30% から 70% の間で推移しているので、十分です。diskIO は、アプリ マシンでは実質的にゼロであり、データベース サーバーでは最小限です。ネットワークは本当に素晴らしいです。

また、redgate を使用してコード プロファイリングを行いましたが、ロックを待機しているメソッドはありません。スレッドがインスタンスを共有していないことが役立ちます。現在、データベース接続の確立/プーリングなど、より微妙な項目をチェックしています (20 個のスレッドが同じデータベースに接続しようとした場合、それらは互いに待機する必要がありますか?)。

20 スレッドの実行が次のようになるように、リソースの競合を特定して対処しようとしています。

20 threads
  Total thread time: 60 minutes. (Worked 0% longer)
  Total wall clock time: 6 minutes.  10 times speed up

その競合を見つけるために調べる必要がある最も可能性の高い情報源 (ビッグ 4 以外) は何ですか?


各スレッドが実行するコードは、おおよそ次のとおりです。

Run ~50 compiled LinqToSql queries
Run ILOG Rules
Call WCF Service which runs ~50 compiled LinqToSql queries, returns some data
Run more ILOG Rules
Call another WCF service which uses devexpress to render a pdf, returns as binary data
Store pdf to network
Use LinqToSql to update/insert. DTC is involved: multiple databases, one server.

WCF サービスは同じマシン上で実行されており、ステートレスであり、複数の同時要求を処理できます。


マシンには 8 つの CPU があります。

4

3 に答える 3

3

あなたが説明しているのは、スレッド s の増加と wallcklock 時間の減少の間の 1:1 の関係である 100% のスケーラビリティが必要であるということです...これは通常、目標ですが、到達するのは困難です...

たとえば、1 GB の空き容量があるため、メモリの競合はないと書いています... これは私見ですが、間違った仮定です... メモリの競合は、2 つのスレッドがメモリを割り当てようとすると、1 つが待機する必要があることも意味します。その他...心に留めておくべきもう1つのポイントは、すべてのスレッドを一時的にフリーズするGCによって発生する中断です...GCは構成(gcServer)を介して少しカスタマイズできます-http://blogs.msdn.com/b/を参照してくださいclyon/アーカイブ/2004/09/08/226981.aspx

もう1つのポイントは、WCFサービスと呼ばれることです...スケールアップできない場合-たとえば、PDFレンダリング-、それも競合の一種です...

可能性のある競合のリストは「無限」です...そして、あなたが言及した明らかな領域に常にあることはほとんどありません...

編集 - コメントによると:

チェックするポイント:

  • 接続プーリング
    どのプロバイダーを使用していますか? どのように構成されていますか?
  • PDF レンダリング
    の可能な競合は、使用するライブラリ内のどこかで測定されます...
  • Linq2SQL
    これらすべてのクエリの実行計画を確認してください...いくつかの種類のロックが発生し、DB サーバー側で競合が発生する可能性があります...

編集2:

Threads
これらのスレッドは ThreadPool からのものですか? もしそうなら、あなたはスケーリングしません:-(

編集3:

ThreadPool スレッドは、シナリオの場合の長時間実行タスクには適していません...詳細については、を参照してください

http://www.yoda.arachsys.com/csharp/threads/printable.shtmlから

長時間実行される操作では、新しく作成されたスレッドを使用する必要があります。実行時間の短い操作では、スレッド プールを利用できます。

極端なパフォーマンスが必要な場合は、 CQRSとLMAXとして説明されている実際の例を確認する価値があります。

于 2011-10-20T05:23:53.537 に答える
2

はい、リソースの競合があります。すべてのスレッドは、たとえば、同じ RAM モジュールに向けられた同じメモリ バスに対してデータを読み書きする必要があります。空き RAM の量は関係ありません。読み取り/書き込みが同じ RAM モジュールの同じメモリ コントローラーによって実行され、データが同じバスを介して伝送されることが重要です。

どこかに何らかの同期がある場合、それも競合するリソースです。I/Oがある場合、それは競合リソースです。

1 スレッドから N スレッドに変更しても、N 倍のスピードアップは見られません。最終的に、CPU 内のすべてがある程度の競合が発生する共有リソースであるため、これは不可能です。

完全な線形スピードアップを得ることを妨げる要因はたくさんあります。データベース、データベースが実行されているサーバー、それをクライアントに接続するネットワーク、クライアント コンピューター、両端の OS とドライバー、メモリ サブシステム、ディスク I/O、およびその間のすべてが機能していると想定しています。スレッド数を 1 から 20 にすると、20 倍速くなります。

2つの言葉:夢を見てください。

これらのボトルネックのそれぞれが数パーセント遅くなるだけでよく、全体的な結果はあなたが見ているようなものになります.

微調整してスケーリングを改善できると確信していますが、奇跡を期待しないでください.

しかし、キャッシュ ラインの共有は、あなたが探すかもし​​れないことの 1 つです。スレッドは、他のスレッドが使用するデータに非常に近いデータにアクセスしますか? どのくらいの頻度でその発生を回避できますか?

于 2011-10-20T07:30:19.200 に答える
2

合計スレッド時間を測定する代わりに、なんらかの I/O (データベース、ディスク、ネットなど) を実行する各操作の時間を測定します。

スレッド数が多いほど、これらの操作に時間がかかることがわかると思います。これは、その I/O の反対側で競合が発生しているためです。たとえば、データベースがデータの整合性のために要求をシリアル化している場合があります。

于 2011-10-20T07:14:40.280 に答える