3

ArrayfunがGPUのforループよりもはるかに高速である理由を誰かに教えてもらえますか?(CPUではなく、実際にはForループの方がCPUで高速です)

Arrayfun:

x = parallel.gpu.GPUArray(rand(512,512,64));
count = arrayfun(@(x) x^2, x);

そして同等のForループ:

for i=1:size(x,1)*size(x,2)*size(x,3)
  z(i)=x(i).^2;        
end

ForループがGPUでマルチスレッド化されていないことが原因でしょうか?ありがとう。

4

2 に答える 2

3

あなたのループは同等ではないと思います。配列内のすべての要素をCPU実装で二乗しているようですが、 arrayfunに対してある種のカウントを実行しています。

とにかく、あなたが探している説明は次のとおりだと思います。

GPUで実行すると、コードを機能的に分解して(この場合は各配列セルに)、別々に2乗することができます。の値は、他のセルの他の値に依存しないため、これは問題iありません。最も可能性が高いのは、配列getがSバッファーに[cell_i]^2分解されることです。ここで、 SはGPUが持つストリーム処理ユニットの数です。次に、各ユニットは、そのバッファの各セルのデータの2乗を計算します。結果は元の配列にコピーされ、カウントに返されます。

心配しないでください。*array_fun*が実際に行っているように見えるものを数えている場合、同様のことが起こっています。ほとんどの場合、アルゴリズムは配列を同様のバッファーに分割し、各セルを2乗する代わりに、値を加算します。この最初のステップの結果は、同じプロセスを再帰的に適用して新しい合計をカウントできる小さな配列と考えることができます。

于 2012-04-14T04:44:11.717 に答える
1

こちらのリファレンスページhttp://www.mathworks.co.uk/help/toolbox/distcomp/arrayfun.htmlによると、「評価のために渡されたMATLAB関数はGPU用にコンパイルされ、GPU上で実行されます」。明示的なforループバージョンでは、各操作はGPUで個別に実行され、これによりオーバーヘッドが発生しarrayfunます。バージョンは1つのGPUカーネル呼び出しです。

于 2012-04-16T08:24:45.433 に答える