1.并行性
1.1 并行计算
在应用程序设计中有两种基本的并行类型:任务并行、数据并行,CUDA适合数据并行计算。
数据并行程序设计第一步就是把数据依据线程划分,有两种划分方式:块划分(block partitioning)、周期划分(cyclic partitioning)。
块划分:一组连续的数据被分到一个块内,每个数据块以任意次序被安排给一个线程,线程通常在同一时间只处理一个数据。每个线程作用于一部分数据块,通常这些数据块具有相同的大小。
周期划分:较少的数据被分到一个块内,相邻的线程处理相邻的数据块,每个线程可以处理多个数据块。每个线程作用于数据的多部分。
CPU核心比较重,用来处理非常复杂的控制逻辑,以优化串行程序执行
GPU核心比较轻,用于优化具有简单控制逻辑的数据并行任务,注重并行程序的吞吐量
1.2 异构计算
同构计算使用的是同一架构下的一个或多个处理器来执行一个应用
异构计算使用一个处理器架构来执行一个应用,为任务选择合适他的架构,使其最终对性能有所改进。
一个典型的异构计算节点包括两个多核CPU插槽和两个或多个众核GPU。GPU不是独立运行的平台,而是CPU的协处理器,要通过PCIe总线与基于CPU的主机相连进行操作。
异构应用包括两部分:主机代码、设备代码
1.3 CUDA
CUDA程序包含:CPU上运行的主机代码、GPU上运行的设备代码
以下例程运行环境为VS2019、1050ti、cuda_11.4.0_471.11_win10 、cudnn-11.4-windows-x64-v8.2.2.26
#include<stdio.h>
#include"cuda.h"
#include"cuda_runtime.h"
#include"device_launch_parameters.h"
// __global__ 是CUDA在标准C中添加的一个限定符,告诉编译器此函数在设备(GPU)上运行
__global__ void helloFromGPU() {
printf("Hello World from GPU!\n");
}
int main(int argc, char** argv) {
printf("Hello World from CPU!\n");
// 从主机上调用设备代码 << <1, 10 >> >表示在设备上的1个块中的10个线程运行helloFromGPU 函数
helloFromGPU << <1, 10 >> > ();
system("pause");
return 0;
}
运行结果