最近看了看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...