すべての答えがありません。うまくいけば、私はそれにいくつかの光を当てることができます。
.NETのスレッドモデルに関する以前のステートメントを簡素化するには、Parallel LibraryがTasksを使用し、Tasksの既定のTaskSchedulerがThreadPoolを使用することを知ってください。階層を上に行くほど(ThreadPoolが一番下になります)、アイテムを作成する際のオーバーヘッドが大きくなります。余分なオーバーヘッドは確かに遅くなるという意味ではありませんが、そこにあることを知っておくと良いでしょう。最終的に、マルチスレッド環境でのアルゴリズムのパフォーマンスは、その設計次第です。連続してうまく機能するものは、並行して同様に機能しない場合があります。複雑で速いルールを与えるにはあまりにも多くの要因が関係しているため、あなたがしようとしていることに応じて変化します。ネットワークリクエストを処理しているので、簡単な例を示します。
私はソケットの専門家ではなく、Zeroc-Iceについてほとんど何も知らないことを述べさせてください。私は非同期操作について少し知っていますが、これは本当に役立つでしょう。ソケットを介して同期要求を送信する場合、を呼び出すとSocket.Receive()
、要求を受信するまでスレッドがブロックされます。これは良くありません。スレッドはブロックされているため、これ以上リクエストを行うことはできません。Socket.Beginxxxxxx()を使用して、I / O要求が行われ、ソケットのIRPキューに入れられ、スレッドは続行されます。つまり、スレッドは実際には何もブロックせずにループで何千ものリクエストを行うことができます!
私が正しく理解している場合、テストコードでZeroc-Iceを介した呼び出しを使用しており、実際にはHTTPエンドポイントに到達しようとはしていません。その場合、Zeroc-Iceの仕組みがわからないことは認められます。ただし、ここにリストされているアドバイス、特にパートに従うことをお勧めしますConsider Asynchronous Method Invocation (AMI)
。ページにこれが表示されます。
AMIを使用することにより、クライアントは呼び出しが送信されるとすぐに(または、すぐに送信できない場合はキューに入れられて)制御のスレッドを取り戻し、クライアントはそのスレッドを使用してその間に他の有用な作業を実行できます。
これは、上記で.NETソケットを使用して説明したものと同等のようです。多くの送信を行う際にパフォーマンスを向上させる方法は他にもありますが、ここから始めるか、そのページにリストされている他の提案から始めます。あなたはあなたのアプリケーションの設計について非常に曖昧だったので、私は上記よりも具体的にすることができます。覚えておいて、必要なことを行うために絶対に必要なスレッドより多くのスレッドを使用しないでください。
擬似コードのいくつかの例(実際に学習する必要なく、できるだけ氷に近づけようとしました):
var iterations = 100000;
for (int i = 0; i < iterations; i++)
{
// The thread blocks here waiting for the response.
// That slows down your loop and you're just wasting
// CPU cycles that could instead be sending/receiving more objects
MyObjectPrx obj = iceComm.stringToProxy("whateverissupposedtogohere");
obj.DoStuff();
}
より良い方法:
public interface MyObjectPrx : Ice.ObjectPrx
{
Ice.AsyncResult GetObject(int obj, Ice.AsyncCallback cb, object cookie);
// other functions
}
public static void Finished(Ice.AsyncResult result)
{
MyObjectPrx obj = (MyObjectPrx)result.GetProxy();
obj.DoStuff();
}
static void Main(string[] args)
{
// threaded code...
var iterations = 100000;
for (int i = 0; i < iterations; i++)
{
int num = //whatever
MyObjectPrx prx = //whatever
Ice.AsyncCallback cb = new Ice.AsyncCallback(Finished);
// This function immediately gets called, and the loop continues
// it doesn't wait for a response, it just continually sends out socket
// requests as fast as your CPU can handle them. The response from the
// server will be handled in the callback function when the request
// completes. Hopefully you can see how this is much faster when
// sending sockets. If your server does not use an Async model
// like this, however, it's quite possible that your server won't
// be able to handle the requests
prx.GetObject(num, cb, null);
}
}
スレッドをより多く!=ソケットを送信しようとするとき(または実際に何かをするとき)のパフォーマンスが向上することに注意してください。スレッドは、作業中の問題を自動的に解決するという点で魔法ではありません。理想的には、スレッドが待機に多くの時間を費やしていない限り、コアごとに1つのスレッドが必要です。コンテキスト切り替えが発生し、リソースが浪費されるため、各要求を独自のスレッドで実行するのは悪い考えです。(それについて私が書いたものをすべて見たい場合は、編集をクリックして、この投稿の過去の改訂版を見てください。手元の主な問題を曇らせているように見えたので削除しました。)
1秒間に大量のリクエストを行う場合は、スレッドでこれらのリクエストを確実に行うことができます。ただし、スレッドの作成で行き過ぎないでください。バランスを見つけて、それにこだわる。非同期モデルと同期モデルを使用すると、パフォーマンスが向上します。
それがお役に立てば幸いです。