OpenCL并行编程基础 第六章 OpenCL事件和队列

2023-11-13

任务队列允许程序员通过编辑直接创建、管理和调度任务。队列中的命令按提交命令的顺序执行,队列中的吓一跳命令必须等待当前命令执行完后才能开始执行。不同命令队列的先后执行顺序得不到保证。

6.1 命令、命令队列和事件

命令队列保证FIFO:

/*
    启动顺序任务队列的代码
*/
cl_uint num_devices;
cl_device_id devices[1];
errNum = clGetDeviceIDs(NULL, CL_DEVICE_TYPE_CPU, 1, &devices[0], &num_devices);
context = clCreateContext(0, 1, devices, NULL, NULL, &errNum);
cl_command_queue queue_cpu;
queue_cpu = clCreateCommandQueue(context, devices[0], 0/* 顺序执行 */, &errNum);
/*向队列中插入任务*/

乱序队列:

queue_cpu = clCreateCommandQueue(context, devices[0], CL_QUEUE_OUT_OF_ORDER_EXEC_MEOD_ENABLE,&errNum);

单一队列会导致大量计算资源没有用到,故可以使用多队列机制。:

cl_uint num_devices;
cl_devices_id devices[2];

errNum = clGetDevicesIDs(NULL, CL_DEVICES_TYPE_CPU, 1, &devices[0], &num_devices);
errNum = clGetDevicesIDs(NULL, CL_DEVICES_TYPE_GPU, 1, &devices[1], &num_devices);
context_cpu = clCreateContext(0, 1, &devices[0], NULL, NULL, &errNum);
context_gpu = clCreateContext(0, 1, &devices[1], NULL, NULL, &errNum);
cl_command_queue queue_cpu,queue_gpu;
queue_cpu = clCreateCommandQueue(context_cpu, devices[0], 0, &errNum);
queue_gpu = clCreateCommandQueue(context_gpu, devices[1], 0, &errNum);
//CPU、GPU的两个队列对应两个自己的上下文,互相不可见,也不存在sync,常会出错

上面这个问题要将CPU、GPU放在一个上下文中,然后两个队列的任务统一派送到该上下文中,但会出现内存访问不能进行同步的问题。

cl_uint num_devices;
cl_devices_id devices[2];

errNum = clGetDevicesIDs(NULL, CL_DEVICES_TYPE_CPU, 1, &devices[0], &num_devices);
errNum = clGetDevicesIDs(NULL, CL_DEVICES_TYPE_GPU, 1, &devices[1], &num_devices);
context = clCreateContext(0, 2, devices, NULL, NULL, &errNum);
cl_command_queue queue_cpu,queue_gpu;
queue_cpu = clCreateCommandQueue(context, devices[0], 0, &errNum);
queue_gpu = clCreateCommandQueue(context, devices[1], 0, &errNum);
//CPU、GPU的两个队列对应两个自己的上下文,互相不可见,也不存在sync,常会出错

所以引入事件机制。

6.2 事件的定义与基本用法

事件(event)是命令相关的数据对象,表示该命令的状态,它的列表

命令状态
状态取值 含义
CL_QUEUED 该命令已经进入了队列
CL_SUBMITTED 该命令已经被主机提交到了该队列对应设备上
CL_RUNNING 该设备正在执行该命令
CL_COPMLETE 该命令已经执行完毕
ERROR_CODE 该命令执行过程中出现了错误

 创建方法,常见的事件来源命令本身

//API原型函数
cl_int clEnqueueNDRangeKernel(
    cl_command_queue commandqueue,
    cl_kernel kernel,
    cl_uint word_dim,
    const size_t *global_work_offset,
    const size_t *global_work_size,
    const size_t *local_work_size,
    cl_uint num_events_in_wait_list,
    const cl_event *event_wait_list,
    cl_event *event
)
事件相关参数
形参 含义
num_events_in_wait_list 该命令要等待的事件的数量
evevt_wait_list 该命令要等待时间的列表
event 该命令所产生的事件

当非零的 num_events_in_wait_list 和有效的 event_wait_list 值传给API时,相应命令将等待至 event_wait_list 中所有的 num_events_in_wait_list 个事件均为CL_COMPLITE或ERROR_CODE时才会执行。 实例:

cl_event events[2];
errNum = clEnqueueNDRangeKernel(commands, kernel_A, 1, NULL, &global, &local, 0, NULL, &events[0]);//无等待
errNum = clEnqueueNDRangeKernel(commands, kernel_B, 1, NULL, &global, &local, 0, NULL, &events[1]);//无等待
errNum = clEnqueueNDRangeKernel(commands, kernel_C, 1, NULL, &global, &local, 2,events, NULL);//等待kernel_A,kernel_B

当不需要对命令精确控制时,可设置参数来忽略事件对象

  1. 将 num_events_in_wait_list 设为0
  2. 将 *event_wait_list 设为NULL
  3. 将 *event 设为NULL

同步点(执行这条命令前要保证提交的所有命令已执行完毕)查询方法

cl_int clEnqueueBarrier(cl_command_queue command_queueu)
//只接受同步点关联的队列,clEnqueueBarrier通过队列来阻塞函数

用户可以通过一个事件来表示队列中命令的完成状态

cl_int clEnqueueMaker(cl_command_queue commandqueue, cl_event *event)
//commandqueue是同步点要提交到的队列,event是同步点要生成的函数,在event变成CL_COMPLETE前,所有等待次事件的命令都将等待

还有用户显示地等待一个或多个事件 clEnqueWaitForEvents(...)

6.3 事件对象与用户事件

事件对象本身的性质,通过三个函数来管理,clGetEventInfo 查询事件对象存放的状态、clRetainEvent 查询事件对象的引用数、clReleaseEvent 减少一个事件对象的引用数;

如果用户事件创建成功,啧clCreateUserEvent函数将返回一个状态为CL_SUBMITTED的事件对象。

cl_event clCreateUserEvent(cl_context context,cl_int *errcode_ret)
cl_int clSetUserEventStatus(cl_event event, cl_int execution_status)
cl_int clWaitForEvents(cl_uint num_events, const cl_event *event_list)

6.5 使用事件进行性能剖析例子

几乎所有命令都可以在产生相应队列时设置CL_QUEUE_PROFILING_ENABLE标志,即可使用clGetEventProfilingInfo函数获得执行时间。

/* Profiling APIs */
extern CL_API_ENTRY cl_int CL_API_CALL
clGetEventProfilingInfo(cl_event            /* event 要剖析的事件 */,
                        cl_profiling_info   /* param_name 计算时间的方式,
                        size_t              /* param_value_size 剖析数据的预期大小*/,
                        void *              /* param_value 返回数据的指针*/,
                        size_t *            /* param_value_size_ret 剖析数据的实际大小尺寸*/) CL_API_SUFFIX__VERSION_1_0;
cl_profiling_info
取值 含义
CL_PROFILING_COMMAND_QUEUE 主机将命令放入队列的时间,单位为纳秒
CL_PROFILING_COMMAND_SUBMIT 命令提交的时间
CL_PROFILING_COMMAND_START 命令开始执行的时间
CL_PROFILING_COMMAND_END 命令结束执行的时间

思路:首先产生命令队列,设置为运行剖析的形式,然后放别获得命令进入队列和执行的时间,然后两个做差

cl_command_queue commandQueue = clCreateCommandQueue(context, device, CL_QUEUE_PROFILING_ENABLE, NULL);//开启运行剖析
cl_event event;
errNum = clEnqueueNDRangeKernel(commandQueue, kernel,2, global_work_offset,globalWorkSize, localWorkSize,0, NULL, &event);
clFinish(commandQueue);
errNum = clWaitForEvents(1,&event);
cl_ulong start, end; double runTime;
size_t return_bytes;
errNum = clGetEventProfilingInfo(event, CL_PROFILING_COMMAND_START, sizeof(cl_ulong),&start,&return_bytes);
errNum = clGetEventProfilingInfo(event, CL_PROFILING_COMMAND_END, sizeof(cl_ulong), &end, &return_bytes);
runTime = (double)(end - start)*1.0e-9;
std::cout << "commandQueue从开始到结束运行时间:" <<runTime<< " 秒"<<std::endl;

PS:我用的是GTX 1060,不支持OpenCL2.0 chapter7 OpenCL2.0高级特征被砍掉啦~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenCL并行编程基础 第六章 OpenCL事件和队列 的相关文章

随机推荐

  • 力扣之两数之和(题号1)

    题目叙述 给定一个整数数组 nums 和一个目标值 target 请你在该数组中找出和为目标值的那 两个 整数 并返回他们的数组下标 你可以假设每种输入只会对应一个答案 但是 你不能重复利用这个数组中同样的元素 示例 给定 nums 2 7
  • 在一个数组中找出两个数,这两个数之和为指定目标值,返回这两个数下标(leecode)(c++)

    本文主要总结在一个数组中取出两个数 这两个数满足条件为 两数之和为制定目标值target 并且函数返回这两个数下表 示例 给定 nums 5 6 7 8 9 10 target 19 因为 nums 4 nums 5 9 10 19 所以返
  • 在Windows下源码编译LLVM(MingW)

    前言 由于最近工作项目需要 需要在windows下基于mingw 即使用gcc编译器 非vc的编译器 编译LLVM 踩坑无数 仅此一记 环境 win10 64位专业版 准备 试过很多种编译方式 最终发现还是msys2比较靠谱 即在windo
  • R语言与机器学习中的回归方法学习笔记

    机器学习中的一些方法如决策树 随机森林 SVM 神经网络由于对数据没有分布的假定等普通线性回归模型的一些约束 预测效果也比较不错 交叉验证结果也能被接受 下面以R中lars包包含数据集diabetes为例说明机器学习中的回归方法 一 数据集
  • JAVA根据模板生成Word文档

    一 需要模板word文件和document xml模板配置文件 首先把word文件重命名后缀改为 zip然后打开 就能在word文件夹下就能找到document xml了 在document xml模板中需要赋值的地方配置好占位符 二 导入
  • CNN调参

    一 学习率 学习率决定了每步权重更新对当前权重的改变程度 其中E w 为我们优化的损失函数 是学习率 学习率太小 更新速度慢 学习率过大 可能跨过最优解 因此 在刚开始训练 距离最优解较远时可以采用稍大的学习率 随着迭代次数增加 在逼近最优
  • 自动化测试框架rf(Robot Framework)的安装

    2022了 还没自己装过rf 网上找了不少文章 或多或少都跟本地环境不太一下 作为新手 把安装过程做一次记录分享 仅供参考 首先 帖一下我自己电脑的基本情况 下面就开始吧 一 JAVA环境安装 现在基本都是java8以上了 所以建议到官网下
  • Node.js中gulp插件的安装使用

    1 Node js说明 gulp是用JavaScript语言编写的运行在Node js平台开发的前端构建工具 是前端开发人员自动处理日常任务的首选工具 gulp cli 启动构建工具的命令行接口 本地gulp 构建时实际运行的程序 gulp
  • [OLED] 利用stm32开发板控制OLED

    一 OLED的介绍 OLED 即有机发光二极管 Organic Light Emitting Diode 又称为有机电激光显示 Organic Electroluminesence Display OELD OLED由于同时具备自发光 不需
  • 连续时间、离散时间信号、模拟和数字信号辨析

    连续时间和离散时间信号 一个信号 它是在时间t的连续值上给出的 就是一个连续时间信号 而一个信号仅在t的离散值上给出则是一个离散时间信号 模拟和数字信号 凡一个信号的幅度在某一连续范围内能够取到任何值的信号就是模拟信号 这意味着一个模拟信号
  • 牛客 124G--组合游戏

    链接 https www nowcoder com acm contest 124 G来源 牛客网 题目描述 2018年4月8日星期日 小龙沉迷于一个叫做组合的游戏 游戏规则是这样的 原本有一个长度为A的大木板 现在把它分成了n份长度可能不
  • Excel如何排序?掌握3种排序方法!

    我是个刚开始学习Excel的新手 对很多Excel的知识都不太熟悉 今天使用Excel进行表格排序时我又遇到了一些问题 请问Excel如何排序呢 希望给我一些建议 在Excel中 排序是一种常见且有用的数据处理操作 它可以帮助您按照特定的规
  • Unbutn20+cuda11+Qt下配置

    首先装CUDA 具体查看其它博客 这里主要介绍如何配置 CONFIG console TARGET test Define output directories CUDA OBJECTS DIR This makes the cu file
  • 面了个阿里拿36K出来的,真是砂纸擦屁股,给我漏了一手

    今年的春招已经结束 很多小伙伴收获不错 拿到了心仪的 offer 各大论坛和社区里也看见不少小伙伴慷慨地分享了常见的面试题和八股文 为此咱这里也统一做一次大整理和大归类 这也算是划重点了 俗话说得好 他山之石 可以攻玉 多看多借鉴还是有帮助
  • js实现图片预加载

    什么是预加载 当页面打开图片提前加载 而且缓存在用户本地 需要用届时直接进行烘托 在浏览图片较多的网页 百度图库 淘宝京东等 能够有更好的用户体会 一张图片的预加载 var img new Image img addEventListene
  • pandas 导入excel_小白学 Python 数据分析(7):Pandas (六)数据导入

    人生苦短 我用 Python 前文传送门 小白学 Python 数据分析 1 数据分析基础 小白学 Python 数据分析 2 Pandas 一 概述 小白学 Python 数据分析 3 Pandas 二 数据结构 Series 小白学 P
  • echarts 生成的canvas只有100px的问题

    在开发中遇到一个问题 使用echarts的时候 生成的canvas宽度不是实际写入的宽度 后面发现 因为使用了el tabs 存在echarts的tab页在刚开始处于display none 所以echarts拿不到页面的宽度 解决办法 在
  • Burp suite ——爆破账户密码(含爆破token防爆破)

    此文章仅供交流学习使用 目录 爆破普通账户密码 设置环境 处理burp suite的抓包数据 开始爆破 爆破token防爆破账户密码 设置环境 处理抓包数据 开始爆破 爆破普通账户密码 设置环境 1 打开火狐访问此网站 更改代理 火狐浏览器
  • 【RocketMQ】消息重试、重试次数设置、死信队列

    文章目录 1 死信队列 1 1 死信特性 1 2 查看死信消息 2 重试次数参数 2 1 Producer端重试 2 2 Consumer端重试 3 1 异常重试 3 2 超时重试 参考 1 死信队列 上一篇 RocketMQ 消息重试中我
  • OpenCL并行编程基础 第六章 OpenCL事件和队列

    任务队列允许程序员通过编辑直接创建 管理和调度任务 队列中的命令按提交命令的顺序执行 队列中的吓一跳命令必须等待当前命令执行完后才能开始执行 不同命令队列的先后执行顺序得不到保证 6 1 命令 命令队列和事件 命令队列保证FIFO 启动顺序