(一)CUDA编程

CPU:擅长流程控制和逻辑处理,不规则数据结构,不可预测存储结构,单线程程序,分支密集型算法

GPU:数据并行计算,规则数据结构,可预测存储模式

一般而言,并行部分在GPU上运行,串行部分在CPU运行,CPU负责总体的程序流程,而GPU负责具体的计算任务,当GPU各个线程完成计算任务后,就将GPU计算结果拷贝到CPU端,完成一次计算任务。

1、CUDA线程模型

CUDA的线程模型从小往大来总结就是:

Thread: 线程,并行的基本单位

Thread Block:线程块,互相合作的线程块,线程块有如下几个特点:允许彼此同步;通过共享内存快速交换数据;

Grid:一组线程块,以1维、2维组织;共享全局内存

Kernel:在GPU上执行的核心程序,kernel函数是运行在某个Grid上的

每一个block和每个thread都有自己的ID,通过相应的索引找到线程和线程块

理解kernel,必须要对kernel的线程层次结构有一个清晰的认识。首先GPU上很多并行化的轻量级线程。kernel在device上执行时实际上是启动很多线程,一个kernel所启动的所有线程称为一个网格(grid),同一个网格上的线程共享相同的全局内存空间,grid是线程结构的第一层次,而网格又可以分为很多线程块(block),一个线程块里面包含很多线程,这是第二个层次。线程两层组织结构如上图所示,这是一个grid和block均为2-dim的线程组织。grid和block都是定义为dim3类型的变量,dim3可以看成是包含三个无符号整数(x,y,z)成员的结构体变量,在定义时,缺省值初始化为1.因此grid和block可以灵活地定义1-dim、2-dim以及3-dim结构,kernel调用时也必须通过执行配置<<<grid,block>>>来指定kernel所使用的网格维度和线程块维度。CUDA的<<<grid,block>>>就是一个多级索引的方法,第一级索引是(grid.xldx,grid.yldy),对应上图例子就是(1,1),通过它我们就能找到这个线程块的位置,然后启动二级索引(block.xldx,block.yldx,block.zldx)来定位到指定的线程。

2、CUDA内存模型

CUDA中的内存模型分为以下几个层次:

每个线程都用自己的registers(寄存器)

每个线程都有自己的local memory(局部内存)

每个线程块内都有自己的shared memory(共享内存),所有线程块内的所有线程共享这段内存资源

每个grid都有自己的global memory(全局内存),不同线程块的线程都可使用

每个grid都有自己的constant memory(常量内存)和texture memory(纹理内存),不同线程块的线程都可使用

线程访问这几类存储器的速度是register>local memory>shared memory>global memory

3、代码表示线程组织模型

由于GPU的线程太多,为GPU的线程划分国(grid)-省(block)-市(thread)的分级。

在一个grid中有很多block,声明一个有4*3个block的grid:dim3 grid(4,3);
gridDim.x=4;     gridDim.y=3
深绿色block(blockIdx.x=0,blockIdx.y=0)有自己的位置:
blockIdx.x=0;      blockIdx.y=0;  //第一行 第一列
让定义一个 3*2个thread的block:     dim3 block(3,2);
thread也有自己的位置。浅绿色(threadId.x=0,threadId.y=0)的Thread的位置:
blockIdx.x=3;    blockIdx.y=0;       //block 第一行 第四列
threadId.x=0;  threadId.y=0;       //thread 第一行 第一列

4、CUDA和C++结合编程中错误异常

在代码实现过程中cuda的plus<<<>>>()函数总是报错。错误信息:语法错误:”<”

头文件plus.h:

#include <stdlib.h>
#include <device_launch_parameters.h>
#include <cuda_runtime.h>
#include <iostream>
extern "C" {
    void pl();
}

源文件plus.cu

#include "plus.h"
__global__ void plus(float a[], float b[], float c[], int n) {
  int i = blockDim.x * blockIdx.x + threadIdx.x;
  c[i] = a[i] + b[i];
};
void pl() {
  float *A, *Ad, *B, *Bd, *C, *Cd;
  int n = 1024 * 1024;
  int size = n * sizeof(n);
  A = (float*)malloc(size);  // CPU端分配内存
  B = (float*)malloc(size);
  for (size_t i = 0; i < n; i++)  //初始化数组
  {
    A[i] = 90;
    B[i] = 10;
  }
  cudaMalloc((void**)&Ad, size);  // GPU端分配内粗
  cudaMalloc((void**)&Bd, size);
  cudaMalloc((void**)&Cd, size);
  cudaMemcpy(Ad, A, size, cudaMemcpyHostToDevice);  // CPU的数据拷贝到GPU端
  cudaMemcpy(Bd, B, size, cudaMemcpyHostToDevice);
  //定义kernel执行配置,(1024*1024/512)个block,每个block里面有512个线程
  dim3 dimBlock(512);
  dim3 dimGrid(n / 512);
  plus<<<dimGrid, dimBlock>>>(Ad, Bd, Cd, n);  // kernel
  free(A);
  free(B);
  cudaFree(Ad);
  cudaFree(Bd);
  cudaFree(Cd);
}

test.cpp文件中:

#include "plus.h"
int main(){ pl(); }

在CMakeLists.txt文件中

cmake_minimum_required(VERSION 2.8)
find_package(CUDA REQUIRED)
cuda_add_executable(squaresum test.cpp plus.cu)

5、设置VScode支持.cu文件语法高亮及跳转的方法

插件:vscode插件商店搜索cudacpp进行安装后,可支持语法高亮以及<<<>>>等cuda专用符号。

参考《VScode 为 *.cu文件 添加高亮及c++ intelligence相关操作的方法》,设置settings文件,添加文件cu后缀文件与cpp的关联:"files.associations":{"*.cu":"cpp"}。设置完成后可支持cpp的语法高亮与跳转。

NVIDIA CUDA编程指南.pdf GPU系列技术文档.....................................................................................................................1 NVIDIA CUDA 编程指南.........................................................................................................................1 Chapter1 介绍CUDA…….....................................................................................................................11 1.1 作为一个并行数据计算设备的图形处理器单元………………………….............................................11 1.2 CUDA: 一个在GPU上计算的新架构..............................................................................................12 Chapter2 编程模型............................................................................................................................... 15 2.1 一个超多线程协处理器.....................................................................................................................15 2.2 线程批处理.......................................................................................................................................15 2.2.1 线程块..........................................................................................................................................16 2.2.2 线程块栅格.................................................................................................................. 2.3 内存模
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值