cuda與cpu高斯列主消元求解線性方程組速度比較

2021-10-24 15:40:28 字數 2670 閱讀 6013

最近看了看cuda上面用c語言進行的程式設計,踩了很多的坑,在這裡記錄一下。

完整程式已上傳:

配置環境:vs2017  cuda10.0  runtime,cpu:i5 8600k ,顯示卡:gtx 1060

求解公式是:a*x = b,   a: n*n方陣,x:n維列向量,b: n維列向量,求解未知量x向量。

求解方法:分別在gpu與cpu上進行高斯列主消元,比較執行的時間。

求解的過程分為三步:

1、求最大值進行行交換。

2、消元。

3、回代。

程式分為兩部分,第一部分用cuda實現,第二部分在cpu實現,並分別統計執行時間。最終得出結論當矩陣維度大於1000時gpu執行速度快於cpu,而當矩陣維度小於等於1000時gpu執行速度慢於cpu。程式中有很多地方可以進行優化例如使用共享記憶體、執行緒塊的分配,由於題主只是證明cuda在解線性方程可以進行加速所以就沒有進行更細節的優化。

cuda程式:

__global__ void gausskernela(),單執行緒執行該函式來求解第k步時第k列的最大值並把該最大值所在的行交換到第k行。

__global__ void gausskernela(double *augmentedmatrixgpu, int k, int n) 

} if (s != k)

}}

__global__ void augmented(),__global__ void gausskernelb,高斯消元。

__global__ void augmented(double *augmentedmatrixgpu, int k, int n) 

}

__global__ void gausskernelb(double *augmentedmatrixgpu, int k, int n) 

}

所有的核函式都用的是一維陣列進行資料的儲存,並把ax = b,a與b進行合併以增廣矩陣的形式進行儲存。先用cudamemcpy把資料從cpu 拷貝到gpu,再用cudadevicesynchronize()進行gpu執行緒同步然後在開始計時,在cpu  for迴圈中進行邏輯控制,把矩陣的消元與計算放到gpu中執行。(坑1:在計時停止前一定要加cudadevicesynchronize(),因為cpu與gpu是非同步執行的,在for迴圈結束時gpu的可能仍在執行,若不加同步函式,計時函式(queryperformancecounter(&stop))就會在gpu沒有執行完之前就停止計時,導致時間不準確我當時不加同步函式,計時為:0.02ms左右,加同步函式,計時為:1.5ms)。本次計算只進行消元的計時,回代是在cpu上完成的。

cudamemcpy(augmentedmatrixgpu, augmentedmatrix, sizeof(double)* n * (n + 1), cudamemcpyhosttodevice);

cudadevicesynchronize();

queryperformancecounter(&start);

for (int k = 0; k < n - 1; k++)

cudadevicesynchronize();

queryperformancecounter(&stop);

time = 1000 * (stop.quadpart - start.quadpart) / frequence;

printf("gpu time is : %fms", (time));

cudamemcpy(augmentedmatrix, augmentedmatrixgpu, sizeof(double)* n * (n + 1), cudamemcpydevicetohost);

cpu:高斯消元程式

queryperformancecounter(&sta);  //計時開始

for (int k = 0; k < n - 1; k++)

} if (cols != k)

} if (!d[k][k])

for (int p = k + 1; p < n; p++)

} }x[n - 1] = d[n - 1][n] / d[n - 1][n - 1]; //回代

for (int i = n - 2; i >= 0; i--)

x[i] = s / d[i][i];

} queryperformancecounter(&sto); //計時結束

time2 = 1000 * (sto.quadpart - sta.quadpart) / frequence;

printf("cpu time is : %fms\n", time2);

執行時間比較:

矩陣:1000*1000

矩陣: 1500*1500

矩陣: 2000*2000

列主元的高斯消元法(FORTRAN)

program guass1 real,dimension allocatable arr real,dimension allocatable x real a integer i,j,k,n 輸入 輸出數列 write 請輸入需要計算的係數矩陣的大小n read n allocate arr n...

高斯列主消元詳解及模板

分類 高斯消元 2013 08 29 19 28 213人閱讀收藏 舉報高斯消元 採用高斯先列主元消元法求解線性方程組ax b 方法說明 以4階為例 1 第1步消元 在增廣矩陣 a,b 第一列中找到絕對值最大的元素,將其所在行與第一行交換,再對 a,b 做初等行變換使原方程組轉化為如下形式 注 代表...

高斯消元(浮點數主列法消元,有剪枝細節

1 include 2 include 3 include 4 include 5 using namespace std 6const double eps 1e 8 7 8 typedef vectorvec 9 typedef vectormat 1011 vec gauss const ma...