zoukankan      html  css  js  c++  java
  • CUDA学习(三)之使用GPU进行两个数组相加

     传入两个数组,在GPU中将两个数组对应索引位置相加

    #include "cuda_runtime.h"
    #include "device_launch_parameters.h"
    
    #include <iomanip>
    #include <iostream>
    #include <stdio.h>
    
    using namespace std;
    
    //检测GPU
    bool CheckCUDA(void){
        int count = 0;
        int i = 0;
    
        cudaGetDeviceCount(&count);
        if (count == 0) {
            printf("找不到支持CUDA的设备!
    ");
            return false;
        }
        cudaDeviceProp prop;
        for (i = 0; i < count; i++) {
            if (cudaGetDeviceProperties(&prop, i) == cudaSuccess) {
                if (prop.major >= 1) {
                    break;
                }
            }
        }
        if (i == count) {
            printf("找不到支持CUDA的设备!
    ");
            return false;
        }
        cudaGetDeviceProperties(&prop, 0);
        printf("GPU is: %s
    ", prop.name);
        cudaSetDevice(0);
        printf("CUDA initialized success.
    ");
        return true;
    }//使用一维数组相加
    __global__ void addForOneDim(double *a, double *b, double *c, int N);
    
    //初始化一维数组
    void InitOneDimArray(double *a, double b, int N);
    
    int main(){
        //检测GPU
        if (!CheckCUDA()){
            cout << "No CUDA device.";
            return 0;
        }

      //****数组相加************************************************************************************************************************ cout << "****************************************数组相加*********************************************************************" << endl; int N = 20; //定义数组大小 double *h_a_one, *h_b_one, *h_c_one; //声明在CPU上使用的指针 double *d_a_one, *d_b_one, *d_c_one; //声明在GPU上使用的指针 //为数组分配大小 h_a_one = new double[N]; h_b_one = new double[N]; h_c_one = new double[N]; cudaMalloc((void **)&d_a_one, sizeof(double)*N); //在GPU上分配内存空间 cudaMalloc((void **)&d_b_one, sizeof(double)*N); cudaMalloc((void **)&d_c_one, sizeof(double)*N); //为数组初始化 InitOneDimArray(h_a_one, 1.1, N); InitOneDimArray(h_b_one, 2.2, N); //使用GPU中分配的指针指向CPU中的数组 cudaMemcpy(d_a_one, h_a_one, sizeof(double)*N, cudaMemcpyHostToDevice); cudaMemcpy(d_b_one, h_b_one, sizeof(double)*N, cudaMemcpyHostToDevice); //调用核函数,使用1个线程块N个线程 //addForOneDim<<<1, N>>>(h_a_one, h_b_one, d_c_one, N); //不能使用h_a_one和h_b_one,只能使用GPU上定义的指针,不然结果如图一所示 addForOneDim<<<1, N>>>(d_a_one, d_b_one, d_c_one, N); //结果如图二所示
      //调用核函数,使用N个线程块,每个线程块中包含1个线程
      //addForOneDim<<<N, 1>>>(d_a_one, d_b_one, d_c_one, N); //结果如图三所示 //将GPU上计算好的结果返回到CPU上定义好的变量 cudaMemcpy(h_c_one, d_c_one, sizeof(double)*N, cudaMemcpyDeviceToHost); //打印结果 for (int i = 0; i < N; i++){ cout << h_a_one[i] << " + " << h_b_one[i] << " = " << h_c_one[i] << endl; } cout << endl << endl; system("pause"); return 0; } //使用一维数组相加 __global__ void addForOneDim(double *a, double *b, double *c, int N){ int tid = threadIdx.x; //线程索引,启用1个线程块,每个线程块N个线程 if (tid < N){ c[tid] = a[tid] + b[tid]; } } //初始化一维数组 void InitOneDimArray(double *a, double b, int N){ for (int i = 0; i < N; i++){ a[i] = (i+1) * b; //cout << a[i] << endl; } }

     图一 (该图是错误的)

     图二 (该图是正确的)

    图三 (该图是错误的)当在调用核函数时,

    addForOneDim<<<N, 1>>>(d_a_one, d_b_one, d_c_one, N);

    使用的索引是

    int tid = threadIdx.x;      //对应的是一个线程块中每个线程id

    正确的索引是 

    int tid = blockIdx.x;       //对应的是每个线程块id

  • 相关阅读:
    类 2020年8月19
    随便一写,明天改正
    os模块 2020年8月16
    time 模块 2020年8月16
    collections模块 2020年8月16
    正则跟re模块内容2020年8月16日
    【C++设计模式二】C++工厂模式
    【C++设计模式一】C++简单工厂模式
    【01-springmvc快速入门、组件解析】
    03-【Spring 的 AOP】
  • 原文地址:https://www.cnblogs.com/xiaoxiaoyibu/p/10089172.html
Copyright © 2011-2022 走看看