2011-07-26 7 views
0

HPCを使用してシミュレーションを実行したいが、私はSOAを使用するつもりだ。私はいくつかのサンプルの材料から次のコードを持っています、私はそれを修正しました(私はこれを最初に追加しました)。現在、私は最適化の問題/性能の悪さを見つけました。この基本的なサンプルは、何もサービスメソッドを照会することを期待していません。このメソッドは、パラメータとして取得する戻り値です。しかし私の例は遅いです。私は4つのコアプロセッサと1Gbのネットワークを持つ60台のコンピュータを持っています。メッセージを送信する最初のフェーズは約2秒かかるので、戻り値のためにさらに7秒待たなければなりません。同時に、すべての値が1つ以上の値になります。私が持っているもう一つの問題はセッションオブジェクトを再利用することができないということです。なぜならこれはまず外部を使っていて、内部に入れたいのですが、その後タイムアウトになるか、BrokerClientが終了したという情報です。HPCでSOAリクエストを最適化する方法

BrokerClientまたはDurableSessionオブジェクトを再利用できますか。

メッセージ転送のこのプロセス全体をスピードアップするにはどうすればよいですか?

static void Main(string[] args) 
{ 
    const string headnode = "Head-Node.hpcCluster.edu.edu"; 
    const string serviceName = "EchoService"; 
    const int numRequests = 1000; 
    SessionStartInfo info = new SessionStartInfo(headnode, serviceName); 
    for (int j = 0; j < 100; j++) 
    { 
    using (DurableSession session = DurableSession.CreateSession(info)) 
    { 
     Console.WriteLine("done session id = {0}", session.Id); 
     NetTcpBinding binding = new NetTcpBinding(SecurityMode.Transport); 
     using (BrokerClient<IService1> client = new BrokerClient<IService1>(session, binding)) 
     { 
     for (int i = 0; i < numRequests; i++) 
     { 
      EchoRequest request = new EchoRequest("hello world!"); 
      client.SendRequest<EchoRequest>(request, i); 
     } 
     client.EndRequests(); 
     foreach (var response in client.GetResponses<EchoResponse>()) 
     { 
      try 
      { 
      string reply = response.Result.EchoResult; 
      Console.WriteLine("\tReceived response for request {0}: {1}", response.GetUserData<int>(), reply); 
      } 
      catch (Exception ex) 
      { 
      } 
     } 

     } 
     session.Close(); 
    } 
    } 
} 

代わりに良く働いているDurableSession、のセッションと第二版が、私は再利用のセッションで問題を抱えている:

using (Session session = Session.CreateSession(info)) 
{ 

for (int i = 0; i < 100; i++) 
{ 
    count = 0; 

    Console.WriteLine("done session id = {0}", session.Id); 
    NetTcpBinding binding = new NetTcpBinding(SecurityMode.Transport); 

    using (BrokerClient<IService1> client = new BrokerClient<IService1>(session, binding)) 
    { 
      //set getresponse handler 
      client.SetResponseHandler<EchoResponse>((item) => 
      { 
       try 
       { 
        Console.WriteLine("\tReceived response for request {0}: {1}", 
        item.GetUserData<int>(), item.Result.EchoResult); 
       } 
       catch (SessionException ex) 
       { 
        Console.WriteLine("SessionException while getting responses in callback: {0}", ex.Message); 
       } 
       catch (Exception ex) 
       { 
        Console.WriteLine("Exception while getting responses in callback: {0}", ex.Message); 
       } 

       if (Interlocked.Increment(ref count) == numRequests) 
        done.Set(); 

      }); 

     // start to send requests 
     Console.Write("Sending {0} requests...", numRequests); 

     for (int j = 0; j < numRequests; j++) 
     { 
      EchoRequest request = new EchoRequest("hello world!"); 
      client.SendRequest<EchoRequest>(request, i); 
     } 
      client.EndRequests(); 

     Console.WriteLine("done"); 
     Console.WriteLine("Retrieving responses..."); 

     // Main thread block here waiting for the retrieval process 
     // to complete. As the thread that receives the "numRequests"-th 
     // responses does a Set() on the event, "done.WaitOne()" will pop 
     done.WaitOne(); 
     Console.WriteLine("Done retrieving {0} responses", numRequests); 
    } 
} 
// Close connections and delete messages stored in the system 
session.Close(); 
} 

私はEndRequestの第二の実行中に例外を取得:サーバが提供していませんでした意味のある返答。これは、契約の不一致、早すぎるセッションのシャットダウン、または内部サーバーのエラーによって引き起こされる可能性があります。

+0

サンプルコードの変更により、表示されている問題が発生していると思われるようですか? –

+0

あなたはいくつのブローカーノードを使用していますか? –

+0

@Mitch Brokerノード、ヘッドノードは1つだけです。たぶん私の修正は、この問題を導入しています。より効果的なやり方があると思いますが、私はそれを見つけることができません。最初のforループの初期化に1を入れると、タスクを送信したり取得に時間がかかります。 – Darqer

答えて

4
  1. 個別要求が約30秒より短い計算では、DurableSessionを使用しないでください。 DurableSessionは、ブローカ内のMSMQキューによってバックアップされます。あなたの要求と応答はディスクに往復する可能性があります。要求あたりの計算量が少ない場合は、パフォーマンス上の問題が発生します。代わりにSessionを使用してください。
  2. パフォーマンス上の理由から、ブローカーで永続的な動作が絶対に必要な場合以外は、DurableSessionを使用しないでください。この場合、SendRequestsの直後にGetResponsesと呼んでいるので、Sessionは問題なく動作します。
  3. Session.Closeを呼び出していない限り、BrokerClientオブジェクトをいくつでも作成するには、SessionまたはDurableSessionオブジェクトを再利用できます。
  4. クライアント側で応答を並行して処理することが重要な場合は、BrokerClient.SetResponseHandlerを使用して応答を非同期に処理するコールバック関数を設定します(同期を処理するではなく)。詳細については、HelloWorldR2サンプルコードを参照してください。
+0

ありがとうございます。しかし、私はまだ問題があります。セッションを再利用するにはどうすればいいですか?私はセッションオブジェクトにBrokerClientを作成しています。リクエストを送信しています。そして、セッションオブジェクトを閉じるためにEndRequestを使用する必要があります。次のループでこのセッションオブジェクトに別のBrokerClientを作成すると、 EndRequestメソッド? – Darqer

+0

'for'と' using'文の順序を変えましたか? '使用する 'の終わりに、セッションは閉じられるでしょう。 – joXn

+0

私は私の質問に私の現在のコードを入れました。 – Darqer

関連する問題