話不多說,直接上代碼,其實也是比較容易的
只能在Linux下面跑,考慮到有windows的小夥伴,其實把與時間有關的內容刪除就可以了,寫在更下面的了。
#include<math.h>
#include<time.h>
#include <stdio.h>
#include <cuda_runtime.h>
#include <sys/time.h>
using namespace std;
inline double seconds()
{
LARGE_INTEGER cpuFreq;
LARGE_INTEGER startTime;
double runTime=0.0;
QueryPerformanceFrequency(&cpuFreq);
QueryPerformanceCounter(&startTime);
runTime = ((( startTime.QuadPart) * 1000.0f) / cpuFreq.QuadPart);
return runTime;
}
//CUDA 全局變量
__device__ int s;
__device__ int size;
/*
###############################################
## 函數:calc
## 函數描述:計算二維高斯函數的方法。通過公式算出
## 自己的idx,然後從devDataS中得到輸入s值,
## 從devDataLoad中獲取自己的工作負載(即工作循環次數)
## ,然後按照公式進行計算,將結果寫到內存中。
## 參數描述:
## par1:float *c_p,就是一個內存以爲指針,指向爲計
## 算分配好的設備內存
###############################################
*/
__global__ void calc(float *c_p){
int idx =blockDim.x * blockIdx.x + threadIdx.x;
if(idx > size*size) return;
//計算高斯函數
int x = idx/size-3*s;
int y = idx - idx/size*size-3*s;
float part1 = exp((float)(-1.0*(float)(x*x+y*y)/(float)(2*s*s)));
float part2 = 1.0/((float)(s)*sqrt(2*3.1415926535898));
c_p[idx] = part1*part2;
}
/*
###############################################
## 函數:main
## 函數描述:主要進行一下幾步:
## 1.將輸入參數轉爲負載個數,初始化爲2
## 2.確定塊內線程數目,塊的個數,以及每個線程
## 的負載--負責計算次數
## 3.分配設備內存,主機內存
## 4.調用,給定參數
## 5.拷貝設備內存結果,輸出
## 參數描述:
## par1:int argc,參數個數
## par2:char const *argv[],獲取輸入參數的char *
###############################################
*/
int main(int argc, char const *argv[])
{
double startTime = seconds();
int sigma = 2;
if(argc >=2)
sigma = atoi(argv[1]); //工作負載
cudaMemcpyToSymbol(s, &sigma, sizeof(int));
//分塊和格,參考CUDA權威編程
int block = 256;
int size = 6*s+1;
int grid = size*size+255/block;
cudaMemcpyToSymbol(size, &size, sizeof(int));
long real_space = size*size*sizeof(float);
//主機內存
float *h_result;
// h_result = (float *)malloc(real_space);
cudaMallocHost((float **)&h_result,real_space );
//GPU內存
float *d_result;
cudaMalloc((void**)&d_result,real_space);
//開始調用
calc<<<grid,block>>>(d_result);
int ret = cudaMemcpy(h_result, d_result, real_space, cudaMemcpyDeviceToHost);
//釋放內存
cudaFreeHost(h_result);
cudaFree(d_result);
cudaDeviceReset();
double endTime = seconds();
printf("time %.4lf ms",endTime-startTime);
return 0;
}
#include<math.h>
#include<time.h>
#include <stdio.h>
#include <cuda_runtime.h>
using namespace std;
//CUDA 全局變量
__device__ int s;
__device__ int size;
/*
###############################################
## 函數:calc
## 函數描述:計算二維高斯函數的方法。通過公式算出
## 自己的idx,然後從devDataS中得到輸入s值,
## 從devDataLoad中獲取自己的工作負載(即工作循環次數)
## ,然後按照公式進行計算,將結果寫到內存中。
## 參數描述:
## par1:float *c_p,就是一個內存以爲指針,指向爲計
## 算分配好的設備內存
###############################################
*/
__global__ void calc(float *c_p){
int idx =blockDim.x * blockIdx.x + threadIdx.x;
if(idx > size*size) return;
//計算高斯函數
int x = idx/size-3*s;
int y = idx - idx/size*size-3*s;
float part1 = exp((float)(-1.0*(float)(x*x+y*y)/(float)(2*s*s)));
float part2 = 1.0/((float)(s)*sqrt(2*3.1415926535898));
c_p[idx] = part1*part2;
}
/*
###############################################
## 函數:main
## 函數描述:主要進行一下幾步:
## 1.將輸入參數轉爲負載個數,初始化爲2
## 2.確定塊內線程數目,塊的個數,以及每個線程
## 的負載--負責計算次數
## 3.分配設備內存,主機內存
## 4.調用,給定參數
## 5.拷貝設備內存結果,輸出
## 參數描述:
## par1:int argc,參數個數
## par2:char const *argv[],獲取輸入參數的char *
###############################################
*/
int main(int argc, char const *argv[])
{
int sigma = 2;
if(argc >=2)
sigma = atoi(argv[1]); //工作負載
cudaMemcpyToSymbol(s, &sigma, sizeof(int));
//分塊和格,參考CUDA權威編程
int block = 256;
int size = 6*s+1;
int grid = size*size+255/block;
cudaMemcpyToSymbol(size, &size, sizeof(int));
long real_space = size*size*sizeof(float);
//主機內存
float *h_result;
// h_result = (float *)malloc(real_space);
cudaMallocHost((float **)&h_result,real_space );
//GPU內存
float *d_result;
cudaMalloc((void**)&d_result,real_space);
//開始調用
calc<<<grid,block>>>(d_result);
int ret = cudaMemcpy(h_result, d_result, real_space, cudaMemcpyDeviceToHost);
//釋放內存
cudaFreeHost(h_result);
cudaFree(d_result);
cudaDeviceReset();
return 0;
}