基于Cuda的异构并行计算
- 不同于C语言的调用,CUDA的内核函数调用时需要指定总的线程数量,以及相应的线程布局(grid和block维度配置)
- 并行运算的主要目的是提高运算速度
- 计算原则是一个大的问题往往可以被划分为很多可以同时解决的小问题
- 并行计算通常设计到两个方面
计算机架构(硬件方面)
并行程序设计(软件方面)
- 高性能计算的关键部分是中央处理单元(cpu)
- 一个程序应包含两个基本的组成部分:指令和数据
- 在应用程序中有两种基本的并行类型:数据并行和任务并行
任务并行的重点在于利用多核系统对任务进行分配
数据并行的重点在于利用多核系统对数据进行分配
数据并行的第一步是把数据依据线程进行划分,有两种方法对数据进行划分:块划分(block partitioning)和周期性划分(cyclic partitioning)
单指令单数据SISD:传统计算机,一种串行架构
单指令多数据SIMD:并行架构,有多个核心,只有一个指令流处理不同的数据流
多指令单数据MISD:每个核心通过多个指令流处理同一个数据
多指令多数据MIMD:并行架构,多个核心使用多个指令流来异步处理多个数据流
-
带宽是单位时间内可处理的数据量,通常表示为MB/s,GB/s
-
吞吐量是单位时间内成功处理的运算数量,通常是gflops(每秒十亿次的浮点运算数量)
-
延迟是一个操作从开始到完成所需要的时间,常用微秒来表示
-
计算机架构根据内存组织进行进一步划分,分成两种类型
分布式内存的多节点系统
共享内存的多处理器系统
- 一个异构应用包含主机代码和设备代码
- GPU容量的两个重要特征:CUDA核心数量和内存大小
- 评估GPU的性能:峰值计算性能和内存带宽
- CPU计算适合处理控制密集型任务,GPU计算适合处理包含数据并行的计算密集型任务
- CUDA提供两层API来管理GPU设备和组织线程:CUDA驱动API和CUDA运行时API
- CUDA平台:编译器工具链,编程语言,库,开发者工具
- __global__告诉编译器这个函数会从CPU中调用,然后在GPU上执行
- cudaDeviceReset()用来显式地释放和清空当前进程中与当前设备有关的所有资源。
- CUDA核中有3个关键抽象:线程组的层次结构,内存的层次结构,障碍同步
在win11 用vs 跑简单的demo
nvcc hello.cu -o hello
报错
nvcc fatal : Cannot find compiler 'cl.exe' in PATH
把路径添加到环境变量
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\bin\Hostx64\x64
成功运行
- cudaDeviceSynchronize():强制主机并行所有核函数执行
- 重点是学会如何为主机和设备分配内存空间以及如何在CPU和GPU之间拷贝共享数据
- 在GPU内存层次中,最重要的是全局内存和共享内存,全局内存类似于CPU的系统内存,共享内存类似于CPU的缓存,共享内存可以直接由CUDA C的内核直接控制。
- 由一个内核启动所产生的所有线程称为一个网格。同一个网格中的所有线程共享相同的全局内存空间。一个网格由多个线程块构成,一个线程块包含一组线程。