私は、GPU(OpenCL)の助けを借りてC++コードを高速化するためにarrayfireを使用します。私はaf :: arrayの600MB以上を持っています。これは列の次元に沿って反転し、それを転置する必要があります。arrayfireでflipとtransposeのmemcpyを避けるにはどうしたらいいですか?
これまでのところ、私はこれらの操作をC++ルーチンを使って行っていました。私はAFでそれをやりたいのですが、AFライブラリの過度のメモリ使用に気付きました。
1)300MBのアレイ上のどのような操作(フリップやTなど)で900MBを超えるメモリが使用されるべきなのか、私は全く気付きません。 2)配列fooのコピーを作成しないようにする方法を知りたいです。私は、別の関数内で操作をカプセル化することによって、コピーを取り除くと考えました。
私はこのようなコードを持っている:
void prepare_array(af::array &a) {
af::array b = af::flip(a, 1); // ~1400MB
a = b.T(); // ~3000MB
}
af::array foo = af::randn(768,16384,3,1,c64); // ~300MB
prepare_array(foo);
af::deviceGC(); // ~600MB
私は速度は、メモリ使用量、その後それほど重要ではないが、私はAFフレームワーク内でこの操作を行うことが好ましいだろうように、一度だけこの操作を行う必要があります。
(すべてのメモリ使用量の統計は、DebianではNVIDIAカーネルドライバパッケージからgpustatで読み出される。)
メモリ使用量があまりにもCPUのバックエンド用として過剰です。
返信ウマル・arshadに感謝:私は、MEM-用法私がCPU上でコードを実行した最後の時間を要したプロファイル - それは同じように振る舞うと仮定。私はGPUでgpustatとnvidia-smiの両方を使って測定値を二重にチェックしました。確かにコードは測定値が違っていて説明した通りでした。それは今、すべての理にかなっている - 少なくともGPUの部分。
おそらくCPU上のfooは、実際の部分のみが使用され、フリップまたはトランスポーズのいずれかによってc64になるため、最初はf64のみです。
このウェブサイトと一緒に「割り当ては、特定のプラットフォーム上のすべてのキューで同期暗黙のデバイスをトリガー」という事実:http://forums.accelereyes.com/forums/viewtopic.php?f=17&t=43097&p=61730&hilit=copy+host+memory+into+an+array#p61727 とAF :: printMemInfo(); は、AFのメモリ処理の大部分を最終的に把握するのに役立ちました。私のプログラムを大幅にスピードアップします。今はまだインプレース(または可能な限り少ないオーバーヘッドで)これら2つの操作を行うための唯一の代替が使用するためしかし
:
// Generate/store data in std::array<af::cdouble> foo_unwrap = new af::cdouble[768*16384*3*1];
// Flip/Transpose foo_unwrap in plain C/C++, like in:
// for(column = 0; column < max_num_column/2; column++)
// swap column with max_num_column-1-column
//
// http://www.geeksforgeeks.org/inplace-m-x-n-size-matrix-transpose/
// but for Column-Major Order matrices
//
// and afterwards whenever needed do ad-hoc:
af::cdouble* first_elem = (af::cdouble*) &(foo_unwrap[0]); // to ensure correct type detection via AF
af::array foo = af::array(768,16384,3,1, first_elem, afDevice);
私はしたくなかったので、しかし、これは非常に面倒です行/列メジャー形式と索引マジックについて気にする。だからまだ私はここで提案を探している。
ええ、私は 'gpustat'が何をしているのか分かりませんが、数字は事実上間違っています(下記のUmarの答えを参照してください)。より良い情報のために 'nvidia-smi'を使うことができます。また、 'af :: deviceMemInfo'を使って、arrayfireが内部で何をしているのかを知ることができます。 –
通常、私がArrayFireを扱うとき、私は次元を第1次元、列、行ではなく第2次元として扱います。あなたが一貫している限り、次元の表現は重要ではありません。もちろん、これは線形代数演算には適用されませんが、AF(matmul)の一部の関数では、データを並べ替えることなく配列が転置されたかのように計算を実行するオプションパラメータがあります。アプリケーションに関する追加のコンテキストも役立ちます。 SOはこのタイプの議論のための最良のフォーラムではありません。私たちはかなりグーグルグループや巨人に積極的です。 –