2013-09-25 45 views
0

我看到CUBLAS可能是一個有效的算法包,用於單個大矩陣乘法或加法等。但在一個常見的設置中,大多數計算都是依賴的。所以下一步依賴於前一步的結果。cublas:相同的輸入和輸出矩陣可獲得更好的性能?

這會導致一個問題,因爲輸出矩陣必須與CUBLAS例程中的輸入矩陣不同(因爲輸入矩陣是常量),因此需要花費很多時間來處理malloc空間並將數據從設備複製到這些臨時矩陣。

所以是有可能做的事情一樣乘法(A,A,B),其中第一個參數是輸出中矩陣和第二/第三輸入矩陣,以避免額外的存儲器操作的時間?還是有更好的解決方法?

非常感謝!

回答

4

不,不可能使用CUBLAS執行像gemm這樣的就地操作(實際上,我不知道有任何並行BLAS實現可以確保這樣的操作可行)。

說了這麼多,此評論:

....太多的時間都花費malloc的空間和設備的數據複製到設備這些臨時矩陣。

讓我想你可能會俯瞰明顯。儘管需要爲臨時矩陣分配空間,但在使用此類分配時,無需執行設備到設備內存副本。這:

// If A, B & C are pointers to allocations in device memory 
// compute C = A*B and copy result to A 
multiply(C, A, B); 
cudaMemcpy(A, C, sizeA, cudaMemcpyDeviceToDevice); 
// now A = A*B 

可以通過

multiply(C, A, B); 
float * tmp = A; A = C; C = tmp; 

即進行更換。您只需交換主機上的指針即可執行設備到設備內存拷貝的等效功能,但不需要GPU時間成本。這不能用於任何情況(例如,有一些就地塊操作可能仍需要顯式存儲器傳輸),但在大多數情況下,可以避免顯式的設備到設備存儲器傳輸。

如果用CUBLAS大密集操作的存儲成本限制了你的應用程序,考慮調查"out of core" approaches與大型密集矩陣工作。

1

你可以預先頁頭緩衝區矩陣,墊MUL操作之前,輸入矩陣A複製到緩衝區中。

Memcopy(buff, A); 
Multiply(A, buffer, B); 

通過重用緩衝區,你不需要每次分配的緩衝區,開銷將只有一個MEM複製每個墊子MUL。當矩陣足夠大時,開銷的時間成本將佔用非常小的部分,可以忽略。