乙個用GPU寫的矩陣乘法

2021-09-26 06:53:39 字數 3577 閱讀 6794

這個過程相當繁瑣,個人認為有優化的可能:

先說一下思路,矩陣相乘a矩陣乘b矩陣相當於a矩陣和b矩陣的轉置做內積.所以我就先把b矩陣做了轉置,再做內積.其中有兩個核函式是在主函式中執行的,先執行轉置,再執行乘法.再乘法函式中又巢狀了乙個內積函式.這樣充分的利用了並行化.

如圖所示:

以3*3矩陣為例.我先開3*3個執行緒做內積運算,然後在每個執行緒中又開了1*3個執行緒做內積運算.其中求和部分我沒有用並行方式求和而是使用序列方式求和的,個人認為這是乙個可以優化的點.還有乙個優化點就是,個人認為不必要算矩陣的轉置就可以實現內積,只不過在乘法中演算法變一下就行了.以後有機會討論優化問題.這樣我就開了3*3*3等於27個執行緒.這樣求出的矩陣乘法.

一會看看其他人的演算法思路是否有借鑑之處,這是本人的gpu求矩陣的乘法的思路.思想很簡單,但是不是很成熟,有更簡單的演算法一起討論學習.

**使用:

輸入乙個數為矩陣的維度,**會自動生成兩個n*n的隨機矩陣.然後相乘得到另外的矩陣.

實驗結果:

請輸入矩陣的維度:

3cpu記憶體資料h_a:

h_a[0][0] = 2 h_a[0][1] = 4 h_a[0][2] = 10

h_a[1][0] = 9 h_a[1][1] = 7 h_a[1][2] = 3

h_a[2][0] = 8 h_a[2][1] = 10 h_a[2][2] = 9

cpu記憶體資料h_b:

h_b[0][0] = 2 h_b[0][1] = 0 h_b[0][2] = 8

h_b[1][0] = 7 h_b[1][1] = 4 h_b[1][2] = 8

h_b[2][0] = 6 h_b[2][1] = 1 h_b[2][2] = 6

cpu記憶體資料h_bt:

h_bt[0][0] = 2 h_bt[0][1] = 7 h_bt[0][2] = 6

h_bt[1][0] = 0 h_bt[1][1] = 4 h_bt[1][2] = 1

h_bt[2][0] = 8 h_bt[2][1] = 8 h_bt[2][2] = 6

gpu記憶體資料:

h_c[0][0] = 92 h_c[0][1] = 26 h_c[0][2] = 108

h_c[1][0] = 85 h_c[1][1] = 31 h_c[1][2] = 146

h_c[2][0] = 140 h_c[2][1] = 49 h_c[2][2] = 198

執行結束

**:

#include #include #include #include __global__ void zhuanshi(int *d_b,int *d_bt,int n)

__global__ void neiji(int *d_a,int *d_bt,int *d_c,int *d_data,int ictdx,int icbdx,int n)

d_c[ictdx * n + icbdx] = temp;

}__global__ void chengfa(int *d_a,int *d_bt,int *d_c,int *d_data,int n)

int main()

else

}while(blag);

/*******申請主機記憶體*********/

int *h_a = (int*)malloc(sizeof(int) * n * n);

int *h_b = (int*)malloc(sizeof(int) * n * n);

int *h_c = (int*)malloc(sizeof(int) * n * n);

int *h_bt = (int*)malloc(sizeof(int) * n * n);

/*******初始化主機記憶體資料********/

srand(time(null));//設定隨機數值

for(int i = 0; i < n * n; ++i)

/*******申請裝置記憶體*******/

int *d_a,*d_b,*d_c,*d_bt,*d_data;

cudamalloc((void**)&d_a,sizeof(int) * n * n);

cudamalloc((void**)&d_b,sizeof(int) * n * n);

cudamalloc((void**)&d_c,sizeof(int) * n * n);

cudamalloc((void**)&d_bt,sizeof(int) * n * n);

cudamalloc((void**)&d_data,sizeof(int) * n * n * n);

/******主機記憶體資料複製到裝置記憶體中************/

cudamemcpy(d_a,h_a,sizeof(int) * n * n,cudamemcpyhosttodevice);

cudamemcpy(d_b,h_b,sizeof(int) * n * n,cudamemcpyhosttodevice);

/*******執行核函式******/

zhuanshi<<>>(d_b,d_bt,n);

chengfa<<>>(d_a,d_bt,d_c,d_data,n);

/*****裝置記憶體資料複製到主機記憶體中*****/

cudamemcpy(h_bt,d_bt,sizeof(int) * n * n,cudamemcpydevicetohost);

cudamemcpy(h_c,d_c,sizeof(int) * n * n,cudamemcpydevicetohost);

std::cout << "cpu記憶體資料h_a:" << std::endl;

for(int i = 0; i < n; ++i)

printf("\n");

} std::cout << "cpu記憶體資料h_b:" << std::endl;

for(int i = 0; i < n; ++i)

printf("\n");

} std::cout << "cpu記憶體資料h_bt:" << std::endl;

for(int i = 0; i < n; ++i)

printf("\n");

} std::cout << "gpu記憶體資料:" << std::endl;

for(int i = 0; i < n; ++i)

printf("\n");

} /*******釋放記憶體*********/

free(h_a);

free(h_b);

free(h_c);

free(h_bt);

cudafree(d_a);

cudafree(d_b);

cudafree(d_c);

cudafree(d_bt);

cudafree(d_data);

std::cout << "執行結束" << std::endl;

return 0;

}

用python寫乙個蛇形矩陣

蛇形矩陣,如 10 11 12 1 9 16 13 2 8 15 14 3 7 6 5 4從右上角大回環,其實挺簡單,思路想明白了就順了。這樣的矩陣可以看做二維陣列,python對陣列的寫法很麻煩,用numpy生成就簡單多了 myarray np.zeros n,n dtype np.int16 有...

乙個矩陣乘法的問題

問題 1024階雙精度浮點矩陣相乘,矩陣滿秩 經典 for i 0 i n i 這是比較經典的方式,發現乙個問題,1024階的時間居然比1025階的時間多不少,很令人費解,於是加了一些類似gettimeofday這種函式統計計算每乙個行,每乙個結果的時間,發現在1024的時候沒隔一定個數的元素,時間...

用golang寫乙個proxy

我複雜的網路環境中,proxy是個很有用的工具,我們可以通過proxy 幫我們完成網路流量的 這個proxy得先能接收請求,所以這裡先啟動乙個tcp的監聽,獲取請求 func s server start glog.infof proxy listen in s,waiting for connec...