CUDA和OpenCL都是实现计算机异构并行计算架构,然而CUDA是针对NVIDIA公司的GPU,而OpenCL是一种通用的计算框架。两者基本的差别为:
表 4 CUDA与OpenCL基本差别
CUDA | OpenCL | |
---|---|---|
技术类型 | 控制 | 开源和VIP服务 |
出现时间 | 2006年 | 2008年 |
SDK企业 | NVIDIA | 具体根据企业 |
SDK是否免费 | Yes | 依赖企业 |
实现企业 | 仅NVIDIA | Apple、NVIDIA、AMD、IBM |
支持系统 | Windows, Linux, Mac OS X; 32 and 64‐bit | 依赖具体企业 |
支持设备类型 | 仅NVIDIA GPU | 多种类型 |
支持嵌入式设备 | NO | Yes |
1. 硬件架构
1.1 芯片结构
CUDA和OpenCL的芯片结构类似,都是按等级划分的,并逐渐提高等级。然而OpenCL更具通用性并使用更加一般的技术,如OpenCL通过使用Processing Element代替CUDA的Processor,同时CUDA的模型只能在NVIDIA架构的GPU上运行。
1.2 存储结构
CUDA和OpenCL的存储模型如图20所示,两者的模型类型,都是将设备和主机的存储单元独立分开,它们的都是按等级划分并需要程序员进行精确的控制,并都能通过API来查询设备的状态、容量等信息。而OpenCL模型更加抽象,并为不同的平台提供更加灵活的实现,在CUDA模型的Local Memory在OpenCL没有相关的概念。对于CUDA和OpenCL模型的类似概念,通过表5列出两者对存储单元命名的差异。
表 5 CUDA与OpenCL存储器对比
OpenCL | CUDA |
---|---|
Host memory | Host memory |
Global memory | Global or Device memory |
Global memory | Local memory |
Constant memory | Constant memory |
Global memory | Texture memory |
Local memory | Shared memory |
Private memory | Registers |
2. 软件架构
2.1 应用框架
一个典型的应用框架都包含有libraries、API、drivers/compilies和runtime
system等来支持软件开发。CUDA和OpenCL也拥有相似的特性,都拥有runtime API和library API,但具体环境下的创建和复制API是不同的,并且OpenCL可以通过平台层查询设备的信息;CUDA的kernel可以直接通过NVIDIA 驱动执行,而OpenCL的kernel必须通过OpenCL驱动,但这样可能影响到性能。因为OpenCL毕竟是一个开源的标准,为了适应不同的CPU、GPU和设备都能够得到正常执行;而CUDA只针对NVIDIA的GPU产品。
2.2 编程模型
- 开发模型
CUDA和OpenCL应用的开发模型基本一致,都是由Host和Device程序组成。程序首先开始执行Host程序,然后由Host程序激活Device程序kernel执行。其中两者也存在一些差别,如表6所示。
表 6 CUDA与OpenCL开发模型比较
CUDA | OpenCL | |
---|---|---|
精确的host和device代码分离 | Yes | Yes |
定制的kernel编程语言 | Yes | Yes |
并行的kernel编程语言 | Yes | 仅有OpenCL C或具体的企业语言 |
支持数据并行kernels | Yes | Yes |
支持任务并行kernels | No | Yes |
多编程接口 | Yes,包括OpenCL | 仅支持标准C的API |
host和device结合程度 | Yes,效率非常高 | No,分离的编译并且kernel和API调用是不相干的 |
Graphics支持 | OpenGL and Direct3D | OpenGL |
- kernel编程
kernel程序是指Device设备上执行的代码,它是直接在设备上执行,受具体设备的限制,具体两者的差别,如表7所示。
表 7 kernel编程差异
CUDA | OpenCL | |
---|---|---|
基于开发语言版本 | 基本C和C++、C++14 | C99 |
访问work-item方式 | 通过内置的变量 | 通过内置函数 |
内置vector类型 | 基本vector类型,没有操作和函数 | vector、literals类型,并内置操作和函数 |
Voting函数 | Yes (CC 1.2 or greater) | No |
Atomic函数 | Yes (CC 1.1 or greater) | Only as extension |
异步内存空间复制和预取函数 | No | Yes |
支持C++语言功能 | Yes,受限,但大部分功能都支持 | No |
- Host 编程
Host端基本是串行的,CUDA和OpenCL的差别主要表现在调用Device的API的差异,所以表8描述了两者之间API的差异。
表 8 Host端可用的API比较
C Runtime for CUDA | CUDA Driver API | OpenCL API |
---|---|---|
Setup | ||
Initialize driver Get device(s) (Choose device) Create context | Initialize plauorm Get devices Choose device Create context Create command queue | |
Device and host memory buffer setup | ||
Allocate host memory Allocate device memory for input Copy host memory to device memory Allocate device memory for result | Allocate host memory Allocate device memory for input Copy host memory to device memory Allocate device memory for result | Allocate host memory Allocate device memory for input Copy host memory to device memory Allocate device memory for result |
Initialize kernel | ||
Load kernel module | Load kernel source | |
(Build program) | Create program object | |
Get module function | Build program | |
Create kernel object bound to kernel function | ||
Execute the kernel | ||
Setup execution configuration | Setup kernel arguments Setup execution configuration Invoke the kernel | Setup kernel arguments Setup execution configuration |
Invoke the kernel (directly with its parameters) | Invoke the kernel | |
Copy results to host | ||
Copy results from device memory | Copy results from device memory | Copy results from device memory |
Cleanup | ||
Cleanup all set up above | Cleanup all set up above | Cleanup all set up above |
3. 性能
本节根据学术上对CUDA和OpenCL的研究,比较两者的性能,其中本文简单以[1-3]研究成功比较CUDA和OpenCL之间的性能差异,若需详细了解CUDA和OpenCL之间的性能差异可以参考[4-15]。
3.1 AES实现
Wang[1]提出一种在XTS模式的AES实现,并对OpenCL和CUDA性能进行比较。如图 22和图23所示,总体性能CUDA要比OpenCL好10%~20%之间。
3.2 三维可视化加速模型
上海理工大学[3]提出合理设计内核函数实现改进的光线投射算法在GPU上并行和并发运行的三维可视化加速模型,该模型实现代码可不用修改在两大主流显卡平台NVIDIA和AMD上任意移植,通过实验证明比较OpenCL与CUDA之间的性能。
3.3 MAGMA和DGEMM算法
作者[2]已经在先前的版本中使用CUDA实现了MAGMA(Matrix Algebra on GPU and multicore
architectures)和DGEMM算法,现在将其实现移植到OpenCL
API,并对两者的性能进行比较。在NVIDIA处理器上进行测试,其结果是CUDA的性能要高于OpenCL。
4. 总结
====
CUDA与OpenCL的功能和架构相似,只是CUDA只针对NVIDIA的产品,而OpenCL是一种通用性框架,可以使用多种品牌的产品,所以CUDA的性能一般情况下要比OpenCL的性能要高10%~20%之间。
CUDA与OpenCL的相似点
- 关注数据并行计算模型;
- 将主机和设备的程序和存储分离;
- 提供定制和标准C语言对设备进行编程;
- 设备、执行和存储模型是现类似的;
- OpenCL已经可以在CUDA之上进行实现了。
CUDA和OpenCL主要的差异点 - CUDA是属于NVIDIA公司的技术框架,只有NVIDIA的设备才能执行;
- OpenCL是一个开源的框架,其目标是定位不同的设备;
- CUDA拥有更多的API和帮助文档;
- CUDA投入市场的时间更早,所以得到更多的支持,并且在研究、产品和应用都比OpenCL丰富;
- CUDA有非常多的文档,但也更加模糊。
References
Wang, X., et al. AES finalists implementation for GPU and multi-core CPU
based on OpenCL. in Anti-Counterfeiting, Security and Identification (ASID),
2011 IEEE International Conference on. 2011: IEEE.Du, P., et al., From CUDA to OpenCL: Towards a performance-portable solution
for multi-platform GPU programming. Parallel Computing, 2012. 38(8): p.
391-407.袁健与高勃, 基于 OpenCL 的三维可视化加速模型. 小型微型计算机系统, 2015.
36(002): 第327-331页.Karimi, K., N.G. Dickson and F. Hamze, A performance comparison of CUDA and
OpenCL. arXiv preprint arXiv:1005.2581, 2010.McConnell, S., et al. Scalability of Self-organizing Maps on a GPU cluster
using OpenCL and CUDA. in Journal of Physics: Conference Series. 2012: IOP
Publishing.Fang, J., A.L. Varbanescu and H. Sips. A comprehensive performance
comparison of CUDA and OpenCL. in Parallel Processing (ICPP), 2011
International Conference on. 2011: IEEE.Oliveira, R.S., et al., Comparing CUDA, OpenCL and OpenGL implementations of
the cardiac monodomain equations, in Parallel Processing and Applied
Mathematics. 2012, Springer. p. 111-120.Harvey, M.J. and G. De Fabritiis, Swan: A tool for porting CUDA programs to
OpenCL. Computer Physics Communications, 2011. 182(4): p. 1093-1099.林乐森, 基于 OpenCL 的 AES 算法并行性分析及加速方案, 2012, 吉林大学.
易卓霖, 基于 GPU 的并行支持向量机的设计与实现, 2011, 西南交通大学.
蒋丽媛等, 基于 OpenCL 的连续数据无关访存密集型函数并行与优化研究.
计算机科学, 2013. 40(3): 第111-115页.-
詹云, 赵新灿与谭同德, 基于 OpenCL 的异构系统并行编程. 计算机工程与设计,
- 33(11): 第4191-4195页.
王晗, 基于多核环境下的多线程并行程序设计方法研究, 2014, 中原工学院.
黄文慧, 图像处理并行编程方法的研究与应用, 2012, 华南理工大学.
刘寿生, 虚拟现实仿真平台异构并行计算关键技术研究, 2014, 中国海洋大学.