话不多说,直接上代码,其实也是比较容易的
只能在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;
}