マイクロソフトロボティクス 並列データ処理

Microsoftの製品の1つであるMicrosoft Roboticsには、Concurrent and Coordination Runtimeライブラリが含まれています。 ロボットは、音と画像(およびそれらだけではない)を処理する際に並列コンピューティングを整理するためのライブラリを本当に必要とします。 投稿では、次の式を使用して、このライブラリを使用して、マトリックスA(m×n要素)にベクトルB(1×n要素)を乗算する並列アルゴリズムを作成する方法を説明します。 。 ベクトルC(m×1要素)を計算するアルゴリズムは、ベクトルのi番目の要素の値が他の要素の値に依存しないため、簡単に並列化できます。 ソースから例を実行する前に、Microsoft Roboticsをインストールすることをお勧めします。

1. Microsoft Roboticsの簡単な紹介


Microsoft Roboticsには、いくつかのコンポーネントが含まれています。

マイクロソフトロボティクスの主要概念:

2.サービスプロジェクトの作成


サービスプロジェクトは、Microsoft RoboticsタブのVisual Studioで作成されます(図1を参照)。


図 1.サービスプロジェクトの作成

プロジェクトを作成したら、サービスを構成する必要があります。プロジェクトの名前、名前空間、サービスが開発されている組織のドメイン、およびサービスが作成された年と月を指定します。 ドメインと日付は、一意のサービス識別子を作成するために使用されます(このプロジェクトでは、この識別子は直接必要ありません)。


図 2.サービスのセットアップ

サービスプロジェクトは、いくつかのファイルで構成されています。

サービスをコンパイルすると、dllライブラリのセットとマニフェストが生成されます。 マニフェスト-開発されたサービスが対話するサービスへのリンクを含むXML形式のファイル。 サービスプロジェクトの設定は、サービスのコンパイル後に作成されたdllライブラリが\ binディレクトリにコピーされるように設定されます。
サービスはdsshostプログラムを使用して起動され、マニフェストとそれに指定されているすべてのサービスがロードされます。

3.サービス構造


サービスコードの構造には、DSSノード(dsshost.exe)がサービスを開始するときに呼び出されるStartメソッドが含まれています(したがって、通常、データを初期化するアクションはStartメソッドに配置されます)。
 protected override void Start() { base.Start(); //   //    } 

プロジェクトをコンパイルすると、3つのdllライブラリが生成されます。

作成したサービスは、Visual StudioのF5だけでなく、コマンドラインからも実行できます。 これを行うには、[スタート]メニューの[MRDS]で[DSSコマンドプロンプト]を選択します。 その結果、シェルウィンドウが起動し、ルートディレクトリと環境変数が設定されます。 開いたウィンドウで、次のコマンドを実行する必要があります。
 dsshost /p:50000 /t:50001 /m:"<    >" 

4.推定リードタイム


計算の実行時間は、Stopwatchクラスを使用して決定されます。
 Stopwatch sWatch = new Stopwatch(); sWatch.Start(); < > sWatch.Stop(); Console.WriteLine(sWatch.ElapsedMilliseconds.ToString()); 

5.コンピューティングの実装


5.1。 データ構造の宣言

マトリックスA、ベクトルBおよびC、サイズをグローバルに保存するための変数を決定します。
 int[,] A; int[] B; int[] C; int m; int n; 

TestFunction()メソッドは計算を開始します。 まず、この方法では、行列に逐次アルゴリズムを使用してベクトルを乗算し、次に並列計算を使用して同じ問題を解決します。 この方法を検討してください。
データ構造が初期化されます。
 nc = 2; //   m = 11000; //    n = 11000; //    A = new int[m, n]; B = new int[n]; C = new int[m]; 

行列AとベクトルBが生成されます。
 Random r = new Random(); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) A[i, j] = r.Next(100); } for (int j = 0; j < n; j++) B[j] = r.Next(100); 

5.2。 逐次乗算アルゴリズム

SequentialMulメソッドを検討してください。
 Stopwatch sWatch = new Stopwatch(); sWatch.Start(); for (int i = 0; i < m; i++) { C[i] = 0; for (int j = 0; j < n; j++) C[i] += A[i, j] * B[j]; } sWatch.Stop(); Console.WriteLine("  = {0} .", sWatch.ElapsedMilliseconds.ToString()); 

5.3。 並列乗算アルゴリズム

並列処理は、計算メソッドの複数のコピーを実行することにより実行されます。 メソッドの各コピーは、ソースデータの特定の部分を処理します。 各メソッドのジョブを記述するために、InputDataクラスが使用されます。
 public class InputData { public int start; //   public int stop; //   } 

クラスの開始/停止フィールドには、計算メソッドのインスタンスを使用して計算されるベクトルCの開始/終了行番号が格納されます。
ParallelMulメソッドを検討してください。
 //       InputData[] ClArr = new InputData[nc]; for (int i = 0; i < nc; i++) ClArr[i] = new InputData 

次に、計算メソッドの各インスタンスの初期データが設定されます。
 //       nc  int step = (Int32)(m / nc); //    int c = -1; for (int i = 0; i < nc; i++) { ClArr[i].start = c + 1; ClArr[i].stop = c + step; c = c + step; } 

ディスパッチャは、2つのスレッドのプールで作成されます。
 Dispatcher d = new Dispatcher(nc, "Test Pool"); DispatcherQueue dq = new DispatcherQueue("Test Queue", d); 

Mul()メソッドの各インスタンスが計算の完了後にメッセージを送信するポートを記述します。
 Port<int> p = new Port<int>(); 

Arbiter.Activateメソッドは、2つのタスク(Mulメソッドの2つのインスタンス)をディスパッチャーキューに入れます。
 for (int i = 0; i < nc; i++) Arbiter.Activate(dq, new Task<InputData, Port<int>>(ClArr[i], p, Mul)); 

Arbiter.Activateメソッドの最初のパラメーターは、タスクの実行を制御するディスパッチャーキューです。2番目のパラメーターは、起動するタスクです。
Arbiter.MultipleItemReceiveメソッドを使用して、ポートpによる2つのメッセージの受信を処理するタスク(レシーバー)が起動されます。
 Arbiter.Activate(Environment.TaskQueue, Arbiter.MultipleItemReceive(true, p, nc, delegate(int[] array) { Console.WriteLine(" "); })); 

レシーバは、計算がいつ完了するかを判断するために使用されます。 2つのメッセージがポートpに到着した後にのみ機能します。 レシーバーで説明されているデリゲートには、乗算プロセスの完了後に実行する必要があるアクションを含めることができます。
Mul()メソッドは、行列の一部にベクトルを掛けます:
 void Mul(InputData data, Port<int> resp) { Stopwatch sWatch = new Stopwatch(); sWatch.Start(); for (int i = data.start; i < data.stop; i++) { C[i] = 0; for (int j = 0; j < n; j++) C[i] += A[i, j] * B[j]; } sWatch.Stop(); Console.WriteLine(" № {0}:   = {1} .", Thread.CurrentThread.ManagedThreadId, sWatch.ElapsedMilliseconds.ToString()); resp.Post(1); } 

Mul()メソッドには2つのパラメーターがあります。
1)メソッドの入力に渡されるパラメーターを定義する配列要素の値を格納するインデックス。
2)計算の完了後に整数が送信される完了ポート。
計算が完了すると、Mulメソッドは整数値をポートpに送信します(送信される値は任意です)。
計算結果を図に示します。 3。


図 3.計算の結果

ソースへのリンク

Source: https://habr.com/ru/post/J204466/


All Articles