GPU を使用してネットワーク上で並列計算を行いたい場合 (C++ AMP の方が優れています)、GPU のメモリ内のネットワーク データを使用するにはどうすればよいですか?
使用する GPU のメモリに隣接リストをコピーするにはどうすればよいですか?
隣接行列は大規模でまばらなネットワークには大きすぎるため、隣接行列を使用したくありません。
CPU (通常の C++ コード) 内にデータがある場合は、C++ amp メソッドを使用して GPU にコピーする必要があります。C++ AMP の概要は、基本を学ぶのに適した場所です。
単純な配列またはベクトルの場合、データを array_view オブジェクトにラップし、restrict(amp) でマークされたメソッドを使用してデータに対して操作を実行する必要があります。
これは私が見つけることができる最も簡単で便利な例です。C++AMP を使用した行列乗算の最適化されていない例です。
いくつかの重要なポイント:
このコードは最適化されていません。最適化された例についてはC++ AMP Book Codeplex プロジェクトの Chapter4フォルダーにある例を参照し、なぜそのように書かれたかについては本を参照してください。Dan H によって提案されたように、MSDN にも例があります。
GPU との間のコピーは、入力array_view
を として宣言してコピー アウトを防止し、出力をconst
呼び出してコピー インを防止することで最小限に抑えられます。discard_data
array_view
array_view::synchronize()
この例では、結果が CPU メモリにコピーされたことを保証するために明示的に呼び出します。array_view データがアクセスされたときに暗黙的なコピーが発生するため、これは厳密には必要ありません。たとえば、要素を読み取ることによってc[i]
。
C++ AMP キューは GPU に対して機能します。そのため、作業は GPU で非同期に実行されます。結果が CPU でアクセスされるか、明示的な同期呼び出しが行われた場合にのみ、完了が保証されます。この点で、 は と同様に動作しstd::future
ます。
コードは次のとおりです。
void MatrixMultiply(std::vector<float>& vC,
const std::vector<float>& vA,
const std::vector<float>& vB, int M, int N, int W)
{
// Create read-only wrappers to the input data.
array_view<const float,2> a(M, W, vA);
array_view<const float,2> b(W, N, vB);
// Create a write-only wrapper to the output data.
array_view<float,2> c(M, N, vC);
c.discard_data();
// Declare a kernel to use one GPU thread per matrix element.
parallel_for_each(c.extent, [=](index<2> idx) restrict(amp)
{
int row = idx[0];
int col = idx[1];
float sum = 0.0f;
for(int i = 0; i < W; i++)
sum += a(row, i) * b(i, col);
c[idx] = sum;
});
// Force a synchronization of the result array_view data onto the CPU.
c.synchronize();
}