0

100 万列 x 100 万行のマトリックスがあります。

私のアルゴリズムは次のことを行う必要があります:

Matrix m  = Matrix(rows,cols)
for (colB: cols){
  vector currColA = m.getcolumn(colA)

  for (colB: cols){
    vector currColB = m.getcolumn(colB)
    result = currColA.dotProduct(colB)
    return result;
}}

または、次のように言うこともできます。

Vectors [] v  = Vectors[]

for (i: v.length){
  vector v1 = v[i]

  for (i: v.length){
    vector v2 = v[i]
    result = v1.dotProduct(v2)
    return result;
}}

私の質問: この問題のためにメモリを割り当ててメモリを初期化する適切な方法は何

ですか?
-または、ベクトルのリストにメモリを割り当ててから、このリストをループする必要がありますか?
-それとも??

私の懸念は、GPU への転送時間を最小限に抑えたいということです。JCublas の hello world の例を 2 つのベクトルでの sgemm 操作に変更して、この種の計算を試みましたが、多数のベクトルで実行すると、転送時間がかかり、gpu アクセラレーションの利点が失われました。

どうも!PS: 実装は任意の Java ライブラリにある可能性があります

4

1 に答える 1

0

一度に 1 つずつ制限を適用しているようです。CPU->GPU コピー、待機、計算、GPU->CPU コピー、待機。ほとんどの人は、メモリ コピーが引き起こす可能性がある暗黙の待機に気づいていません。

オペレーションをパイプライン化できますか? つまり、あなたのループは次のもので構成されていますか?

  • CPU→GPUコピー
  • GPU コンピューティング
  • GPU→CPUコピー

これをパイプライン化するには、(たとえば) 4 つの別個の (順番に) コマンド キューを使用し、各キューで GPU にノンブロッキング転送を発行し、各キューでカーネル実行を発行し、それぞれで GPU->CPU コピーを発行します。順番に並びます。待機するまで両方のバッファが有効であることを保証する必要があります (後述)。これにより、後続のメモリ転送が行われている間に GPU が計算を開始できるようになります。

また、ブロッキングメモリ転送は絶対に使用せず、常にノンブロッキングを使用してください。非常に多くの (8?) 転送ごとに、GPU->CPU コピーのイベント オブジェクトを取得しますが、これが最初の反復でない場合は、最初に最後のイベント オブジェクトを待ちます。これにより、キューが調整され、バッファーを再利用できるようになりますが、操作をオーバーラップすると、転送と計算がオーバーラップしたままになります。転送を 8 回前に待機しているため、キューを空にすることはありません。キューの深さを管理することは重要です。過剰な作業項目は GUI の遅延や作業項目の枯渇を引き起こします。

于 2012-06-14T13:53:42.133 に答える