終於,點燃了GPU技能。現在把自己配置成功經驗寫下來,給想要配置的小夥伴們做個借鑑~
一、配置的環境
windows8.1 x64作業系統
顯示卡:NVIDA GERORCE 830M(渣顯示卡勿吐槽)
vs2013帶openCV2.4.9
二、配置過程
1.下載cuda,官網上https://developer.nvidia.com/cuda-downloads,首頁上能看到的只有CUDA8.0版本,點選紅色箭頭所指出會有別的版本,進去選擇即可,我安裝的是CUDA7.5.18,因為看到網上大多數都是這個版本的= =
這個CUDA7.5版本有900多M,最好用迅雷可以在斷點處接著下,但如果網速好的話瀏覽器下載也ok
2.下載之後就安裝了,這個安裝比較簡單,按照提示一步步預設安裝就好了。】、
3.配置環境變數
安裝完成後,系統會自動生成2個系統變數CUDA_PATH和CUDA_PATH_V7_5,剩下還有5個需要自己新增,新增步驟如下圖所示:
變數名和路徑如下:
變數名:CUDA_SDK_PATH
變數值:C:\ProgramData\NVIDIACorporation\CUDA Samples\v7.5
變數名:CUDA_LIB_PATH
變數值:%CUDA_PATH%\lib\x64
變數名:CUDA_BIN_PATH
變數值:%CUDA_PATH%\bin
變數名:CUDA_SDK_BIN_PATH
變數值:%CUDA_SDK_PATH%\bin\x64
變數名:CUDA_SDK_LIB_PATH
變數值:%CUDA_SDK_PATH%\common\lib\x64
ps:這些是建立在將cuda安裝在預設路徑的基礎上。如果自定義安裝路徑,則變數值應該需要改變,我沒試過不保證能行得通。
4.開啟VS2013建立一個win32控制檯新專案
(1) 新建一個原始檔,選擇CUDA C /C檔案
C:\ProgramData\NVIDIA Corporation\CUDA Samples\v7.5\common\inc
再新增以下兩個庫目錄:
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5\lib\x64
C:\ProgramData\NVIDIA Corporation\CUDA Samples\v7.5\common\lib\x64
cublas_device.lib
cuda.lib
cudadevrt.lib
cudart.lib
cudart_static.lib
cufft.lib
cufftw.lib
curand.lib
cusolver.lib
cusparse.lib
nppc.lib
nppi.lib
npps.lib
nvblas.lib
nvcuvid.lib
nvrtc.lib
OpenCL.lib

將項型別那兒選擇為CUDA C/C 。
5.開啟配置管理器
將平臺改為x64
好了,完工!
6.測試看是否安裝成功
將這段程式copy到剛剛新建的原始檔裡面,執行,如果結果如截圖所示,就說明安裝成功啦
#include "cuda_runtime.h"
#include "cublas_v2.h"
#include <time.h>
#include <iostream>
using namespace std;
// 定義測試矩陣的維度
int const M = 5;
int const N = 10;
int main()
{
// 定義狀態變數
cublasStatus_t status;
// 在 記憶體 中為將要計算的矩陣開闢空間
float *h_A = (float*)malloc (N*M*sizeof(float));
float *h_B = (float*)malloc (N*M*sizeof(float));
// 在 記憶體 中為將要存放運算結果的矩陣開闢空間
float *h_C = (float*)malloc (M*M*sizeof(float));
// 為待運算矩陣的元素賦予 0-10 範圍內的隨機數
for (int i=0; i<N*M; i ) {
h_A[i] = (float)(rand()%10 1);
h_B[i] = (float)(rand()%10 1);
}
// 列印待測試的矩陣
cout << "矩陣 A :" << endl;
for (int i=0; i<N*M; i ){
cout << h_A[i] << " ";
if ((i 1)%N == 0) cout << endl;
}
cout << endl;
cout << "矩陣 B :" << endl;
for (int i=0; i<N*M; i ){
cout << h_B[i] << " ";
if ((i 1)%M == 0) cout << endl;
}
cout << endl;
/*
** GPU 計算矩陣相乘
*/
// 建立並初始化 CUBLAS 庫物件
cublasHandle_t handle;
status = cublasCreate(&handle);
if (status != CUBLAS_STATUS_SUCCESS)
{
if (status == CUBLAS_STATUS_NOT_INITIALIZED) {
cout << "CUBLAS 物件例項化出錯" << endl;
}
getchar ();
return EXIT_FAILURE;
}
float *d_A, *d_B, *d_C;
// 在 視訊記憶體 中為將要計算的矩陣開闢空間
cudaMalloc (
(void**)&d_A, // 指向開闢的空間的指標
N*M * sizeof(float) // 需要開闢空間的位元組數
);
cudaMalloc (
(void**)&d_B,
N*M * sizeof(float)
);
// 在 視訊記憶體 中為將要存放運算結果的矩陣開闢空間
cudaMalloc (
(void**)&d_C,
M*M * sizeof(float)
);
// 將矩陣資料傳遞進 視訊記憶體 中已經開闢好了的空間
cublasSetVector (
N*M, // 要存入視訊記憶體的元素個數
sizeof(float), // 每個元素大小
h_A, // 主機端起始地址
1, // 連續元素之間的儲存間隔
d_A, // GPU 端起始地址
1 // 連續元素之間的儲存間隔
);
cublasSetVector (
N*M,
sizeof(float),
h_B,
1,
d_B,
1
);
// 同步函式
cudaThreadSynchronize();
// 傳遞進矩陣相乘函式中的引數,具體含義請參考函式手冊。
float a=1; float b=0;
// 矩陣相乘。該函式必然將陣列解析成列優先陣列
cublasSgemm (
handle, // blas 庫物件
CUBLAS_OP_T, // 矩陣 A 屬性引數
CUBLAS_OP_T, // 矩陣 B 屬性引數
M, // A, C 的行數
M, // B, C 的列數
N, // A 的列數和 B 的行數
&a, // 運算式的 α 值
d_A, // A 在視訊記憶體中的地址
N, // lda
d_B, // B 在視訊記憶體中的地址
M, // ldb
&b, // 運算式的 β 值
d_C, // C 在視訊記憶體中的地址(結果矩陣)
M // ldc
);
// 同步函式
cudaThreadSynchronize();
// 從 視訊記憶體 中取出運算結果至 記憶體中去
cublasGetVector (
M*M, // 要取出元素的個數
sizeof(float), // 每個元素大小
d_C, // GPU 端起始地址
1, // 連續元素之間的儲存間隔
h_C, // 主機端起始地址
1 // 連續元素之間的儲存間隔
);
// 列印運算結果
cout << "計算結果的轉置 ( (A*B)的轉置 ):" << endl;
for (int i=0;i<M*M; i ){
cout << h_C[i] << " ";
if ((i 1)%M == 0) cout << endl;
}
// 清理掉使用過的記憶體
free (h_A);
free (h_B);
free (h_C);
cudaFree (d_A);
cudaFree (d_B);
cudaFree (d_C);
// 釋放 CUBLAS 庫物件
cublasDestroy (handle);
getchar();
return 0;
}
執行結果截圖:
写评论
很抱歉,必須登入網站才能發佈留言。