栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

cuda编程入门:使用cuda实现矩阵加法

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

cuda编程入门:使用cuda实现矩阵加法

使用cuda实现矩阵加法 1.整体流程
1.申请内存
2.转移拷贝
3.释放空间
4.核函数
2.头文件
  • 关于cuda操作的一些接口都在这个头文件里
#include 
3.申请内存

cudaMalloc()接口

参数含义
void *p内存地址的指针
size_t s申请的内存大小
cudaError_t返回类型
cudaError_t cudaMalloc(void **p, size_t s) 
4.转移拷贝

cudaMemcpy()接口

参数含义
void *dst目标设备指针
const void *src源设备指针
size_t count内存复制的字节大小
cudaMemcpyKind含义
cudaMemcpyHostToDeviceCPU–>GPU
cudaMemcpyDeviceToHostGPU–>CPU
cudaError_t cudaMemcpy(void *dst, const void *src, size_t count, enum cudaMemcpyKind kind);
5.释放空间

cudaFree接口

cudaError_t cudaFree(void *devPtr);
6.核函数

1.定义

  • __global__标志核函数,在host调用,在device上执行
  • 核函数的返回类型必须是void
  • threadIdx线程索引 thread index
  • blockDim线程块维度
  • blockIdx线程块索引 block index
__global__
void vecAddKernel(float* A_d, float* B_d, float* C_d, int n)
{
    // GPU中执行并行计算的thread id
    // 类比CPU中计算数组位置
    int i = threadIdx.x + blockDim.x * blockIdx.x;
    if (i < n) C_d[i] = A_d[i] + B_d[i];
}

2.调用

  • <<< >>> 告诉运行时如何启动设备(调用几个block,调用几个线程)
vecAddKernel <<< blockPerGrid, threadPerBlock >>> (da, db, dc, n);
7.编译与运行

使用nvcc进行编译

# 命令行终端执行
nvcc my_gpu_add.cu -o my_gpu_add

生成可执行文件my_gpu_add
运行

# 参数为执行加法运算的次数,相当于数组的大小
./my_gpu_add 1
8.源代码

附上源代码

// my_gpu_add.cu
#include 
#include 
#include 

// 核函数
__global__
void vectorAddKernel(float * A_d, float * B_d, float * C_d, int n){
    int i = threadIdx.x + blockDim.x * blockIdx.x;
    if(i <= n) C_d[i] = A_d[i] + B_d[i];
}


int main(int argc, char * argv[]){
    int n = atoi(argv[1]);
    std::cout << "执行加法" << n << "次" << std::endl;
    
    // 要申请的内存大小
    size_t size = n * sizeof(float);

    // 先在host上申请内存,生成数据
    // 在CPU上使用 free - malloc 申请内存方式
    float *a = (float*)malloc(size);
    float *b = (float*)malloc(size);
    float *c = (float*)malloc(size);

    // 生成随机数组
    for(int i = 0; i < n; i++){
        float af = rand() / double(RAND_MAX);
        float bf = rand() / double(RAND_MAX);
        a[i] = af;
        b[i] = bf;
    }

    // 定义device指针
    float * da = NULL;
    float * db = NULL;
    float * dc = NULL;

    // 显存申请
    cudaMalloc((void **) &da, size);
    cudaMalloc((void **) &db, size);
    cudaMalloc((void **) &dc, size);

    // 转移拷贝 host --> device
    cudaMemcpy(da, a, size, cudaMemcpyHostToDevice);
    cudaMemcpy(db, b, size, cudaMemcpyHostToDevice);
    cudaMemcpy(dc, c, size, cudaMemcpyHostToDevice);

    // 调用核函数
    vectorAddKernel<<< n/256+1, 256>>> (da, db, dc, n);
    std::cout<<"nblockPerGrid:"< host
    cudaMemcpy(c, dc, size, cudaMemcpyDeviceToHost);

    // 释放显存
    cudaFree(da);
    cudaFree(db);
    cudaFree(dc);

    
    // std::cout<<"a:"<<*a<<"n";
    // std::cout<<"b:"<<*b<<"n";
    // std::cout<<"c:"<<*c<<"n";
    

    // 释放空间
    free(a);
    free(b);
    free(c);
    return 0;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/957753.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号