【OpenCL基础 · 二 】OpenCL架构

news2024/10/6 18:25:15

文章目录

  • 前言
  • 一、OpenCL平台模型
  • 二、OpenCL执行模型
    • 1.上下文
    • 2.命令队列
    • 3.内核的执行——NDRange
  • 三、OpenCL存储器模型
    • 1.存储器区域
    • 2.存储器对象
    • 3.主机与设备的数据交互
  • 总结


前言

通过【OpenCL基础 · 一】因源,我们了解了OpenCL的起源和应用场景。在异构并行平台上,OpenCL可以协助开发者方便地使用计算资源,使得异构平台编程变得容易。

那么如何使用这个便捷的开发工具就是开发人员需要学习的了,我们需要从宏观到细节去理解OpenCL是如何运作的,才能进行实际的代码开发工作。这篇博文将介绍OpenCL的整体框架,展示它是如何利用异构平台进行控制、资源调度及运算的。包括OpenCL平台模型、执行模型和存储器模型。

参考:《OpenCL异构并行计算——原理、机制与优化实践》


一、OpenCL平台模型

平台模型描述了OpenCL是如何看待底层异构硬件平台的,下图是一个非常直观的展示:
在这里插入图片描述
这个图很核心哦~

一个异构平台包括多个、多类型处理器,OpenCL这个小可爱主观上将它们分为主机【Host】和与其相连的一个或多个OpenCL设备【Compute Device】,主机的功能是控制,OpenCL设备的主要功能则是计算。因此主机一般是包含X86或ARM处理器的计算平台,OpenCL设备可以是CPU、GPU、DSP、FPGA等处理器。

每个OpenCL设备包含一个或多个计算单元【Compute Unit,CU】,每个计算单元又由一个或多个处理单元【Processing Element,PE】组成,PE是执行计算的最小单元,不再向下细分。

在实际算法执行过程中,PE就是一个计算核,开发者可以在指定PE上运行代码。列举一个常见的使用场景,我们可以让大量的PE同时运行相同的代码段,不过它们的输入值不同,以此实现SIMT形式的并行运算效果。若将OpenCL设备(以下简称为设备)看作多核处理器的话,那么每个PE就像是一个核。在执行模型中会有详细介绍。

二、OpenCL执行模型

执行模型描述了OpenCL是如何协调主机和设备进行计算的。

实现功能,必然要依靠代码。和平台模型对应,OpenCL 的代码区分为主机端程序和设备端的内核(kernel)程序。主机端程序运行在主机处理器上,它将内核程序和数据从主机提交至设备,设备接收到程序与数据后就在PE上进行计算。计算完成后,主机会从设备端取走运算结果。

OpenCL设备一般不具有IO口,因此数据需要从主机端获取,并且计算结果也要返还给主机。

从这样的工作流中,我们不难发现,内核程序会是一些计算量大、逻辑较简单的函数,而主机程序则是主要的控制程序,掌握整个流程和数据传输。OpenCL提供了丰富的API供主机端使用,开发者可以方便地按照规定流程进行调用,实现一个OpenCL工程。

可以看出内核程序是并行运算的核心,OpenCL定义了以下三种内核:

  • OpenCL内核: 用OpenCL C语言编写,并用OpenCL C编译器编译的函数。所有OpenCL都支持该类型内核的执行。
  • 原生内核: OpenCL之外创建的函数,比如主机端源码中定义的函数,在OpenCL中通过一个函数指针来访问。执行原生内核是一个可选功能。
  • 内建内核: 被绑定至特定设备,不需要源码编译成程序对象的函数,这是OpenCL的扩展功能。常见用法是针对公开固定函数硬件,将它们关联到一个特定设备上,一些处理器厂家会针对自家产品提供一些实用的内建内核。

执行模型的框架如上所述,其具体实施就要依赖三个关键要素:上下文、命令队列和内核。下面对它们逐一介绍。

1.上下文

上下文【context】是主机为了内核程序的顺利运行而创建出来的一个执行环境,它包含以下内容:

  • 设备【Device】:OpenCL平台包含的一个或多个设备,即指定可以运行内核程序的设备。
  • 内核对象【Kernel】:要在设备上运行的内核函数。
  • 程序对象【Program】:实现内核程序的源码和目标二进制码。
  • 存储器对象【MemObject】:对主机和设备可见的存储对象,内核执行时操作这些对象的实例。

在实际开发中,主机端会通过API先创建一个context,将要使用的设备编号会作为参数传入,用于指示使用哪些设备完成之后的内核计算。之后主机在调用相应的API创建内核对象、程序对象等对象时,会把已经建好的context作为参数传进去,表示这些对象都建在这个传入的context中,以此形成对应的关系。

上下文和设备的对应关系:
1、上下文要求其中所关联的设备全部来自同一个平台;对于不同平台的设备,必须创建不同的上下文进行管理。
2、在一个平台中,一台设备可以同时关联到多个上下文中。
3、主机可以使用多个上下文来管理多个设备。
在这里插入图片描述

2.命令队列

在OpenCL架构中,主机通过命令队列与设备进行交互。主机或运行在设备上的内核可以提交命令给命令队列,命令会在队列中等待,直到调度到设备上被执行。一个命令队列在一个上下文中被创建,并关联到一个设备上。

命令可以分为以下三类:

  • 【内核入队命令】将一个内核程序入队至关联了相同设备的命令队列中,等待设备执行。比如对应的API有:
cl_int clEnqueueNDRangeKernel (
cl_command_queue command_queue, cl_kernel kernel, cl_uint work_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)
......
  • 【存储器入队命令】与存储空间设置相关的命令入队。比如主机与设备数据传输的命令、内存空间映射的命令、内存释放命令等。比如对应的API有:
cl_int clEnqueueSVMMemcpy (
cl_command_queue command_queue, cl_bool blocking_copy, void *dst_ptr, const void *src_ptr, size_t size, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event);
cl_int clEnqueueMigrateMemObjects ( 
cl_command_queue command_queue, cl_uint num_mem_objects, const cl_mem *mem_objects, cl_mem_migration_flags flags, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
cl_int clEnqueueWriteBufferRect (
cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_write, const size_t *buffer_origin, const size_t *host_origin, const size_t *region, size_t buffer_row_pitch, size_t buffer_slice_pitch, size_t host_row_pitch, size_t host_slice_pitch, const void *ptr, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
......
  • 【同步命令】对命令队列中需要执行的命令施加执行顺序约束。

命令是异步方式执行,即主机或设备内核提交了命令后不用等命令执行完成,可以直接继续工作。

命令队列中的命令执行顺序包括:

  • 【按序执行】按先入先出的顺序执行命令。
  • 【乱序执行】命令以任意顺序执行,通过显式的同步点或显式事件依赖项来约束顺序。

一般情况下是按序执行,所有OpenCL平台均支持。

3.内核的执行——NDRange

异构平台上可能有多个计算设备,每个设备又有数量众多的核,如何将计算任务分配到各个核上是一个需要考虑的管理问题。OpenCL采用编号的方式来管理任务(即内核程序)实例,每个实例就是在一个处理单元(还记得吗,是平台模型中的PE哦==)上运行的。

主机提交一个内核到设备上运行时,OpenCL会创建一个N维整数索引空间,N可以取1、2或3。这个N维的网格就称为NDRange。
内核程序在设备上执行时,为了利用多核并行性,OpenCL会创建出多个内核实例,一个实例被分配到一个PE上同时运行,它们执行的计算是相同的。我们把实例称为一个工作项(work-item),在NDRange中一个实例就对应网格中的一个点,这个点是用坐标标识的。比如下图是一个二维NDRange,其中最小的一个方块就表示一个工作项,涂黑的那个工作项对应的全局坐标【全局ID】 值就是(6,5)。一般坐标从(0,0)开始。

图中的GX和GY值描述了全局空间的大小,也表明了分配给当前内核程序使用的PE数量。
在这里插入图片描述

为了更多的管理需求,OpenCL将多个工作项组织为一个工作组(work-group),工作组横跨了全局索引空间,提供了对索引空间的粗粒度分解。上图中的NDRange就被划分成9个工作组,每个工作组包含了4x4个工作项。工作组也有自己的索引ID,上图正中间的工作组的ID就是(1,1);同时工作项会被定义一个组内ID(局部ID),来表示工作项在其所属工作组中的位置。
通常情况下,我们使用工作项的全局ID就足够了。

通过上述内容,我们可以进行合理推测,N取1、2、3时分别适配的计算类型为,一维数组计算、二维矩阵计算和三维矩阵计算(三维的情况在卷积神经网络中就很常见了)。

三、OpenCL存储器模型

1.存储器区域

存储是运算过程中必不可少的部分,用于存储运算数据和代码。OpenCL异构平台由主机端和设备端构成,存储器区域包含了主机与设备的内存, 根据功能定义以下几种不同的存储器区域:

  • 【主机内存】主机可以直接使用的内存,通过OpenCL API或共享虚拟存储器接口,实现存储器对象在主机和设备间的传输。
  • 【全局存储器】这个存储器区域允许上下文中任何设备中所有工作组的所有工作项读写。
  • 【常量存储器】属于全局存储器中的一块区域,在内核实例执行器件其保存的数据保持不变,对于工作项而言该存储器是只读的,主机负责对该存储器对象进行分配和初始化。
  • 【局部存储器】该存储器区域对于工作组局部可见,它可以用来分配由该工作组中所有工作项共享的变量。
  • 【私有存储器】该存储器区域是一个工作项的私有区域,其中的变量其他工作项不可见。

以上除了主机内存外,剩下的几种存储器模型都是属于OpenCL设备的。

OpenCL的内存模型如下图所示,其中全局存储器和常量存储器可以在一个上下文内的一个或多个设备间共享,OpenCL设备可能包含缓存来支持对这两个存储器的高效访问。一个OpenCL设备关联自己的局部存储器和私有存储器。
在这里插入图片描述

2.存储器对象

全局存储器中的数据内容通过存储器对象来表示,一个存储器对象就是对全局存储器区域的一个引用。存储器对象可以分为三种类型:

  • 【缓冲 buffer】内核可用的一个连续存储区域,可以将内建数据类型、矢量数据类型等映射到缓冲区,内核通过指针来访问缓冲区。
  • 【图像 image】用于存储标准格式的图像。它是一个不透明的数据结构,使用OpenCL API来管理。
  • 【管道 pipe】管道存储器是数据项有序的队列,同一时刻仅有一个内核实例(即工作项)可以向一个管道内写数据,同一时刻,也仅有一个内核实例可以从一个管道中取数据。

3.主机与设备的数据交互

在计算过程中,主机和设备必然要进行数据交互,OpenCL提供三种交互方式:

  • 【读/写/填充】显示的数据传输方式,需要主机将对应的命令入队,实现数据读写操作。
  • 【映射和解映射】映射是指允许主机将一个存储器区域映射到主机内存的一个区域上,主机就可以直接访问到。在实际操作中,主机先将映射命令入队,实现存储器区域的映射,再对该区域进行读写;完成后再入队一个解映射命令,使得内核可以安全地读写缓冲。
  • 【拷贝】将存储器对象在两个缓冲间拷贝,这两个缓冲可以停留在主机或设备上。

OpenCL 2.0提供了一种新的主机-设备交互方式,称为共享虚拟存储器(Shared Virtual Memory,SVM),有以下三种类型:

  • 【粗粒度SVM】共享发生在OpenCL缓冲存储器对象 区域的粒度;
  • 【细粒度SVM】共享发生在OpenCL缓冲存储器对象里独立地以字节加载/存储的粒度;
  • 【细粒度系统SVM】共享发生在主机内存内任何地方独立地以字节加载/存储的粒度。

简单来说,粗粒度对应区域,细粒度对应字节,系统对应主机内存。


总结

本文对OpenCL的整体架构进行了介绍,实际构建项目时的具体步骤均依托于这些模型进行,因此先在脑海中建立起大框架有助于后续的开发学习。
我也是初学者,内容可能存在理解有误的地方,欢迎大家指正~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1005112.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTTP文件服务

在工作中,往往会需要将文件同时共享给很多台电脑。 本篇介绍HHDESK的HTTP文件服务功能,通过浏览器,将本地资源共享给任意主机。 1 共享文件 首页——资源管理——服务端——“”,在弹出框中选择HTTP文件服务。 填写各项内容。…

计算一个四边形差值结构的稳定性

( A, B )---3*30*2---( 1, 0 )( 0, 1 ) 让网络的输入只有3个节点,AB训练集各由5张二值化的图片组成,让A中有4个1,B中全是0,统计迭代次数并排序。 其中有6组数据 差值结构 迭代次数 构造平均列 L E - - - 34838.43 1 - …

Swing程序设计(3)JDialog窗体

文章目录 前言一、JDialog窗体的介绍二、JDialog窗体的使用 1.JDialog的常用构造方法2.实例展示及分析总结 前言 JDialog窗体是窗体中的另一种类型的窗体,指对话框窗体。与JFrame窗体类似,绝大部分对于JFrame窗体使用的方法,对于JDialog窗体也…

多元共进|整合开发者社区资源,共建繁荣生态

谷歌致力于构建多元社区 促进行业内更多交流和联系 一起来了解 2023 Google 开发者大会上 谷歌如何以点及面 将资源辐射至开发者、数字人才和初创企业 持续赋能开发者社区生态 谷歌全球开发者社区计划的目的是与开发者同在,实现双向对话、互动和参与&#xff0…

Houdini19 命令行启动环境配置

在自动化流程中,通常都是从外部命令行启动 Houdini,而不是在软件里进行烘培和输出。完全体是通过类似 Jenkins 等自动化工具来启动 Houdini 自动生成流程。 我使用的 Houdini 版本为 19.5.640,对应的 Python 版本为 3.9 。 1、配置开发环境 …

Gitlab仓库部署

Gitlab仓库部署 一、Gitlab的概述1、gitlab介绍2、gitlab主要功能3、gitlab和github的区别 二、部署环境1、安装依赖环境2、安装Postfix邮箱3、Gitlab优势4、Gitlab工作流程 三、Gitlab部署过程1、Yum安装Gitlab2、配置gitlab站点URL3、启动并访问Gitlab 四、Gitlab具体操作1、…

挖到宝了!这个中文版SiteGPT竟然有那么多好处

如今数字时代蓬勃发展,信息非常丰富,但个性化互动和量身定制的反馈却相对匮乏。个性化AI工具的出现可以说是打破了窘境。随着人工智能(AI)技术的快速发展,定制AI问答机器人成为了越来越多企业和组织的热门选择。这些智…

Zabbix监控部署项目

为什么选择Zabbix Zabbix 是一个基于 WEB 界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。zabbix 能监视各种网络参数,保证服务器系统的安全运营;并提供灵活的通知机制以让系统管理员快速定位/解决存在的各种问题。 面试常问 你用过哪些监控软件 zabbix …

linux的应用线程同步与驱动同步机制

同步机制 在 Linux 应用程序和内核中的驱动程序中,有一些常见的同步机制用于实现线程或进程之间的同步和数据访问保护。下面是它们的一些主要机制: Linux 应用程序中的同步机制: 互斥锁(Mutex):用于保护共…

233062C++QTday5

实现一个图形类(Shape),包含受保护成员属性:周长、面积, 公共成员函数:特殊成员函数书写 定义一个圆形类(Circle),继承自图形类,包含私有属性:半…

【ArcGIS Pro二次开发】(67):处理面要素空洞

这个一个简单的小功能。 有些面要素可能会存在空洞,这个工具的目的就是获取面要素的空洞,或者去除空洞获取要素的边界。 这个功能其实在之前做拓扑功能的时候就已经有了,这次只是单独把它提取出来。因为有时候会单独用到这个功能。 一、要实…

圆形旋转特效原理及pygame实现

具体效果: 视频教程链接: https://www.bilibili.com/video/BV1ou411F7a2/ 介绍 本文介绍了如何实现一个围绕鼠标旋转的文字效果如何实现,有什么用途,以及pygame的代码实现。 实现代码: import pygame import math…

初识Java 8-1 接口和抽象类

目录 抽象类和抽象方法 接口定义 默认方法 多重继承 接口中的静态方法 作为接口的Instrument 本笔记参考自: 《On Java 中文版》 接口和抽象类提供了一种更加结构化的方式分离接口和实现。 抽象类和抽象方法 抽象类,其介于普通类和接口之间。在构…

华为云云耀云服务器L实例评测|华为云云耀云服务器L实例使用教学+宝塔建站 — 运行Python脚本(保姆级)

目录 文章目录 目录前言一、创建云耀云服务器L实例1、打开购买页面2、找到系统镜像3、进入系统控制台4、重置服务器密码 二、安装宝塔面板1.打开在线安装工具2.复制公网IP3.完成在线安装4.安装完成(记住账密信息)五.开放安全组 三、使用服务器总结 前言 …

Linux系统编程(一):文件 I/O

参考引用 UNIX 环境高级编程 (第3版)黑马程序员-Linux 系统编程 1. UNIX 基础知识 1.1 UNIX 体系结构(下图所示) 从严格意义上说,可将操作系统定义为一种软件,它控制计算机硬件资源,提供程序运行环境,通常…

4.linux的RPM和YUM

一、RPM 1.rpm包的管理 1.1介绍 Linux互联网下载包,类似于windows的setup.exe 1.2rpm简单查询已安装的rpm rpm -qa | grep xxx 当前linux有没有安装火狐 rpm -qa | grep fox 1.3rpm包的格式 一个 rpm 包名:firefox-45.0.1-1.el6.centos.x86_64.…

学习记忆——方法篇——连锁拍照、情景故事和逻辑故事法

三大方法速记这些内容 1、连锁拍照法速记重要事件 2、情景故事速记速记购物信息 3、逻辑故事法速记客户档案 一、连锁拍照法速记重要事件 例:女朋友在出差之前嘱咐男朋友几件事 1、把房间收拾干净,最重要的是要把书架整理了,垃圾倒了 2、记…

软件设计师_计算机组成与体系结构

计算机组成与体系结构 文章目录 1.1 数据的表示1.1.1 进制的转换1.1.2 原码 反码 补码 移码1.1.3 浮点数运算 1.2 计算机结构1.3 Flynn分类法1.4 CISC和RISC1.5 流水线技术1.6 存储系统1.7 总线系统1.8 可靠性1.9 校验码 1.1 数据的表示 1.1.1 进制的转换 R进制转十进制 --&g…

Linux:keepalived + ipvsadm

介绍 Linux:keepalived 双热备份(基础备份web)_鲍海超-GNUBHCkalitarro的博客-CSDN博客https://blog.csdn.net/w14768855/article/details/132815057?spm1001.2014.3001.5501 环境 一台 centos7 keepalived ipvsadm (主…

技术架构图是什么?和业务架构图的区别是什么?

技术架构图是什么? ​技术架构图是一种图形化工具,用于呈现软件、系统或应用程序的技术层面设计和结构。它展示了系统的各种技术组件、模块、服务以及它们之间的关系和交互方式。技术架构图关注系统内部的技术实现细节,以及各个技术组件之…