如何实现C语言程序向CUDA代码的自动化转换技术?
摘要:C2CUDA 目录C2CUDA目标分析CUDA加速的原理C语言中可被有效加速的部分定义定理 目标分析 首先,目标是将C语言转化为CUDA加速程序的运行,从这里我们引出两点需要探究的内容是: CUDA加速的原理是什么? C语言中的什么部分可以
C2CUDA
目录C2CUDA目标分析CUDA加速的原理C语言中可被有效加速的部分定义定理
目标分析
首先,目标是将C语言转化为CUDA加速程序的运行,从这里我们引出两点需要探究的内容是:
CUDA加速的原理是什么?
C语言中的什么部分可以被CUDA有效的加速?
CUDA加速的原理
2006年,NVIDIA推出了统一计算设备架构(CUDA),使任何计算工作负载都能不受图形API的限制,利用GPU的吞吐量能力。
——CUDA编程指南
从上面的引用可以看出,CUDA设计的目的是利用GPU的吞吐量能力(单位时间内系统能处理的任务总量(或数据量))
而CUDA 的核心逻辑是将大规模并行的软件逻辑(Thread)映射到大规模并行的硬件资源(Core)上
因此最核心的原理就是并行,因此C语言中的什么部分可以被CUDA有效的加速?
C语言中可被有效加速的部分
最核心的就是可以并行的部分,那么在一个串行的C语言代码中有什么可以并行呢?
数据并行:在C 语言中,循环(Loop)是数据并行最主要、甚至几乎是唯一的显式表现形式。
任务并行:代码中互不相关的函数调用或代码块也可以并行, 任务并行的规模通常很小(比如同时跑 2-4 个不同的任务),相比于循环动辄上百万次的迭代,它带来的加速效果远不如循环并行明显
指令级并行: 这种并行通常由硬件和后端编译器(如 NVCC)自动优化,通常不需要关注它。
因此,核心目标就是将C语言中的循环利用CUDA并行化运行在不同硬件上。
[!IMPORTANT]
将循环并行化意味着不同循环循环迭代之间的运行顺序是不保证的!
CUDA 执行线程是并发的,硬件调度是不确定的。迭代 \(100\) 可能比迭代 \(1\) 先执行,也可能同时执行。这本质上就是一种极端的“重排序”。
因此要确保并行化有效(不能改变程序的最终结果),就必须识别什么循环可以用并行。这里从一个定理引入
定理 迭代重排序 一个变换重排\(k\)层循环迭代的顺序,此外不做任何其他的改变,如果该循环不携带依赖,那么它是有效的。
**——现代体系结构的优化编译器 ([美] Randy Allen) **
这个定理可以说是本项目研究的基石,项目的入口,因为只有确定什么样的循环迭代能够进行迭代重排序我们才能使用CUDA对其进行并行化。
