经过两天的摸爬滚打,基本上了解了opencl的并行处理的原理和内部调用机制,也上手写代码调试了几个工程。总体感觉opencl会比cuda比起来更复杂一些,但不得不说,平台的兼容性更好,而且调试应该方便些(虽然我的VS调试配置环境始终有问题)。
opencl线程调度方面,注意一下几个方面:
kernel:是指一个用opencl c语言编写的、代表一个单一执行实例的代码单元。opencl c语言看起来跟C语言函数非常相像,都有一个参数列表“局部”变量定义和标准控制流结构。opencl术语中把这种kernel实例称为work-item(工作项)。但opencl kernel与c语方函数的区别在于其并行语义。
work_item:是定义在一个很大的并行执行空间中的一小部分。是并行操作中每一部分的实例化。通俗来说,可以理解为kernel里定义的执行函数。当kernel启动后会创建大量work_item来同时执行,以完成并行任务。work_item根所其数据结构大小可分为一维、二维和三维数据。work_item之是的运行是相互独立的,不同步的。
work_group:opencl将全局执行空间划分为大量大小相等的,一维、二维、三维的work_item集合,这个集合就是work_group。在work_group内部,各个work_item之间允许一定程度的通信。而有work_group保证并发执行来允许其内部的work_item之间的本地同步。
在实际编写内核中,要了解线程调度的维度数,work_group的大小是很重要的,这有利于我们优化编写的内核程序。opencl提供了一此非常有用的函数供我们调用(在内核中调用)。
uint get_work_dim() : 返回线程调度的维度数。
uint get_global_size(uint dimension) : 返回在所请求维度上work_item的总数。
uint get_global_id(uint dimension) : 返回在所请求的维度上当前work_item在全局空间中的索引。
uint get_local_size(uint dimension) : 返回在所请求的维度上work-group的大小。
uint get_local_id(uint dimension) : 返回在所请求的维度上,当前work_item在work_group中的索引。
uint get_number_groups(uint dimension) : 返回在所请求维度上work-group的数目,这个值等于get_global_size 除以 get_local_size。
uint get_group_id(uint dimension) : 返回在所请求的维度上当前wrok_group在全局空间中的索引。
转自:https://www.cnblogs.com/biglucky/p/3755189.html
另外,博主Magnum Programm Life的opencl系类入门文章写的很好,可以借鉴学习: