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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章