我使用arrayfire在GPU(OpenCL)的幫助下加速了一些C++代碼。我有600MB以上的af :: array,我需要沿列維翻轉,然後轉置它。如何避免在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後端太過度。
感謝的答覆歐麥爾-艾爾沙德:當我把異形MEM-使用最後一次,我跑了CPU的代碼 - 假設它會同樣表現。我加倍檢查GPU上的測量結果,並使用gpustat和nvidia-smi。事實上,測量的代碼是不同的,正如你所解釋的那樣。它現在使所有的理想 - 至少是GPU的一部分。
也許在CPU上foo首先只有f64,因爲只有實部被使用,並且通過使用翻轉或換位成爲c64。
,與本網站「分配觸發一個隱含的同步設備上的特定平臺上的所有隊列」在一起的事實:http://forums.accelereyes.com/forums/viewtopic.php?f=17&t=43097&p=61730&hilit=copy+host+memory+into+an+array#p61727 和AF :: printMemInfo(); 幫助我終於弄清楚AF的大部分內存處理。大大加快我的計劃。
但是目前仍然是唯一的替代辦就地這兩個操作(或儘可能少的開銷可能)是使用:
// 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);
然而,這是相當麻煩,因爲我不想麻煩Row/Column-Major格式和索引魔術。所以我在這裏尋找建議。
是的,我不知道'gpustat'在做什麼,但是這些數字實際上是錯誤的(請參考下面的奧馬爾的回答)。你可以使用'nvidia-smi'獲得更好的信息。您也可以使用'af :: deviceMemInfo'來查看內部正在做什麼arrayfire。 –
通常,當我使用ArrayFire時,我將尺寸視爲第一維,第二維而非列,行。只要你是一致的,維度的表示應該不重要。當然,這不適用於線性代數運算,但AF中的一些函數(特別是matmul)具有可選參數,這些參數執行計算,就好像數組已轉置而不重新排序數據。有關您的應用程序的其他上下文也可能有所幫助SO不是這種類型討論的最佳論壇。我們在谷歌組和gitter上非常活躍。 –