CUDA-多核第一次作业-计算高斯函数

话不多说,直接上代码,其实也是比较容易的

只能在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;
}

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值