2017-11-15 16 views
2

ジュリアでは、主に行列を使ってコードを加速して最適化することができました。JuliaでArrayFire経由でGPUに取り組むための最良の方法

- 行ではなく列で作業する、これはJuliaが行列を格納する方法です。

-Onループは、それは歓迎だあなたはお勧めでき@inbounds@simdマクロ

-any機能、マクロやメソッドを使用することができます:D

しかし、私がArrayFire使用時には、上記の例は動作しないようですパッケージはGPUに格納されたマトリックスを使って、CPUとGPUの同様のコードは、GPUの方がはるかに遅くなる場合があるようですが、そうはならないと思います。コードを書く。どんな助けも歓迎されます

答えて

3

GPUコンピューティングは、できるだけ最適化されたGPUカーネルで行う必要があります。 GPUアレイのインデックスは、1つの値をCPUにコピーする小さなカーネルです。これは本当にパフォーマンスが悪いので、GPUArrayのインデックスを決して作成しない限り、決して索引付けする必要はありません(ハードウェアの問題です)。

GPU用のループコードを書く代わりに、ブロードキャスト( "ベクトル化")コードを書き込む必要があります。 v0.6 broadcast changesでは、ブロードキャストされた操作はループと同じくらい効率的です(ただし、this bugにヒットしない限り)ので、汎用コードでそれらを避ける理由はありません。しかし、ルーピングよりもブロードキャストが速く、GPUが大きなケースである場合があります。

なぜか少し説明しましょう。あなたがコードを実行すると:そこにあなたが全体の放送のために融合された匿名関数を持っていることを

broadcast!((b,c,d,e)->b*c + d*e,A,B,C,D,E) 

お知らせ:

@. A = B*C + D*E 

それはその後に低下

A .= B.*C .+ D.*E 

に低下します。 GPUArrayでは、これを上書きして、この融合操作を要素ごとに実行する単一のGPUカーネルが自動的に作成されるようにします。したがって、この操作全体を実行するには、1つのGPUカーネルしか必要ありません。これは、GPUコンピューティングのR/Python/MATLABの方法よりも効率的であることに注意してください。これらのベクトル化された形式は一時的なものであり、ここでは4つのカーネルが必要ですが、これは一時的な配列を持たず、あなた自身でカーネルを書いていたら、それを書いてください。したがって、ブロードキャストを利用すると、GPUの計算が高速になります。

+0

答えをいただきありがとうございます。私は、GPUでの作業がCPUで伝統的なやり方と比較的異なることを知りました。私は線形代数に取り組んでいます.ArrayFireパッケージはいくつかの便利な機能を備えていますが、私が関数を適用しなければならない行列は比較的異なっているからです。例えばスカイラインストレージ(SKS)形式で保存された疎な行列です。行列を格納したり、処理したりすることはできません。要約すると、たくさんのことがあります。ありがとうございます – 4lrdyD

関連する問題