並行程序設計這門課程的課程實驗要求我分別使用串行, 並行+分塊算法, 並行+分塊+SSE指令集加速, CUDA等四種方法來計算矩陣乘法.
還真別說收獲蠻大的.
我的配置是i5 3470+GTX660Ti
下面的表格是各種算法下的情況.
矩陣規模 | 串行 | 多線程+分塊 | 多線程+分塊+SSE | CUDA |
512 | 572.2(ms) | 169.7(ms) | 21.8(ms) | 351.5(ms) |
1024 | 11295.9(ms) | 1367.1(ms) | 134.5(ms) | 395.5(ms) |
2048 | 142193.0(ms) | 10445.7(ms) | 1118.3(ms) | 1051.4(ms) |
4096 | 1213014.6(ms) | 81608.3(ms) | 8737.2(ms) | 6197.3(ms) |
從圖中明顯可以看出, 這個分塊之后cache利用效率大大提高,本來如果普通多線程相對於串行來說不過 4倍,但是這里速度達到了10倍多. 也就是說CPU Cache的合理利用非常有用.
SSE的加速效果就非常厲害了, 相對於分塊又提高了10倍的速度.不過 SSE的浮點數運算准確度好低啊!!!!! 誤差超級大. 但是矩陣的每個點誤差又只有1點幾. 但是每個點都有1點幾, 結果矩陣的所有點的誤差之和就看起來簡直不堪入目.
CUDA的效果簡直非常拔群. 而且時間還包括了傳輸數據到顯卡的時間.
哦,說些閑話.
CUDA的設備變量的地址是分配在操作系統的kernel層的,直接訪問會導致memory access violate錯誤.
比如
Matrix A{ int w;int h; float *d;}; Matrix * A; cudaMalloc((void**)&A,sizeof(Matrix)); A->w = 16; //這里會出錯.!!!
還有,在運行CUDA程序時, Win 8 會有顯卡超時設置,如果你的CUDA程序時間運行太久,顯卡會失去響應,然后windows就自動對顯卡重置. 你的屏幕右下角會出現說,顯卡驅動已停止響應,自動恢復的錯誤. 你的CUDA程序會返回編號為30的UnkownError類型.
需要在注冊表里 設置 關閉windows TDR 或者加長延時上限.
具體參考
http://stackoverflow.com/questions/13177214/disabling-tdr-for-cuda-in-windows-8
http://msdn.microsoft.com/en-us/Library/Windows/Hardware/ff569918(v=vs.85).aspx
代碼地址 http://files.cnblogs.com/tlm1992/matrix_product.zip