2017-02-01 41 views
3

我目前的任務是使用gpu同時訓練多個網絡。我現在不能這樣做,所以現在我嘗試用數組做一些操作。爲什麼repmat和reshape在Matlab中gpuArray這麼慢?

a = rand(1000, 1000, 'gpuArray'); 
tic; for i = 1 : 100 a .* a; end; toc;     % line 1 
tic; for i = 1 : 100 repmat(a, 3, 10); end; toc;  % line 2 
tic; for i = 1 : 100 reshape(a, 10, 10000); end; toc; % line 3 

b = rand(1000, 1000); 
tic; for i = 1 : 100 b .* b; end; toc;     % line 4 
tic; for i = 1 : 100 repmat(b, 3, 10); end; toc;  % line 5 
tic; for i = 1 : 100 reshape(b, 10, 10000); end; toc; % line 6 

所以line 1 falser比line 4但比line 5line 3慢於line 6 並與另一尺寸可以比CPU比GPU快看到repmatreshape其他許多陣列慢 line 2。 有人可以解釋我應該怎麼做才能獲得預期的加速度?

+1

不要修改GPU上的數據。獲取數據到GPU(並修改它)是使用GPU的兩個最慢的部分。 – Suever

+0

那麼,我應該做什麼,而不是'reshape'和'repmat'? – user7484269

+0

你應該用'reshape'和'repmat'在本地創建你的數據,然後*然後*將它作爲'gpuArray'在它的設置大小後強制轉換 – Suever

回答

1

如果您看到任何令人驚訝的事情,您所看到的只是異步執行。 a .* a退出沒有實際做任何事情,它只是設置GPU上的計算。所以你所有的時間是排隊100個內核來執行需要多長時間。您需要使用gputimeitwait(gpuDevice)才能在代碼中獲得正確的時間。也許到時候repmat正在執行隊列限制已達到,所以MATLAB被迫等待一些乘法運算髮生,但我不能確定。

a = rand(1000, 1000, 'gpuArray'); 
b = gather(a); 

fprintf('Times for @times: '); 
fprintf('GPU: %f secs ', gputimeit(@()a.*a)); 
fprintf('CPU: %f secs\n', timeit(@()b.*b)); 

fprintf('Times for @repmat: '); 
fprintf('GPU: %f secs ', gputimeit(@()repmat(a,3,10))); 
fprintf('CPU: %f secs\n', timeit(@()repmat(b,3,10))); 

fprintf('Times for @reshape: '); 
fprintf('GPU: %f secs ', gputimeit(@()reshape(a,10,100000))); 
fprintf('CPU: %f secs\n', timeit(@()reshape(b,10,100000))); 

和輸出:

Times for @times: GPU: 0.000382 secs CPU: 0.001642 secs 
Times for @repmat: GPU: 0.005186 secs CPU: 0.032809 secs 
Times for @reshape: GPU: 0.000053 secs CPU: 0.000002 secs 

reshape大概真的是更快的CPU上(雖然它倒在噪聲),因爲調用對象的方法上不僅需要檢查或修改屬性不再的數組直接。但實際上,對於任何真正的GPU應用來說,這是非常重要的。

如果您的設備上沒有相似的數字,那麼毫無疑問,這與您的GPU的質量有關。 repmat是一個高內存帶寬功能 - 也許你有一個遊戲卡或筆記本電腦芯片,雙精度陣列的性能非常差?你可以在single試試,看看事情是否有所改善。