编写HSA内核

介绍

HSA提供类似于OpenCL的执行模型。指令由一组硬件线程并行执行。在某种程度上,这类似于 单指令多数据(SIMD)模型,但具有这样的便利:细粒度调度对于程序员而言是隐藏的,而不是使用SIMD向量作为数据结构进行编程。在HSA中,编写的代码将同时由多个线程(通常成百上千个)执行。解决方案将通过定义网格工作组 和工作项的线程层次结构进行建模。

Numba的HSA支持提供了用于声明和管理此线程层次结构的工具。

CUDA程序简介

HSA执行模型类似于CUDA。HSA在ROC GPU上采用的内存模型也与CUDA相似。ROC的GPU具有专用于GPU存储器,因此,to_device()与copy_to_host()等需要按照CUDA。

这是CUDA术语到HSA的快速映射:

  • Aworkitem等效于CUDA线程。
  • Aworkgroup等效于CUDA线程块。
  • Agrid等效于CUDA网格。
  • Awavefront等效于CUDA warp。

内核声明

一个核心功能是指从CPU代码称为GPU功能。它具有两个基本特征:

  • 内核无法显式返回值;所有结果数据都必须写入传递给函数的数组中(如果计算标量,则可能传递一个单元素数组);
  • 内核在被调用时显式声明其线程层次结构:即工作组的数量和每个工作组的工作项的数量(注意,虽然内核仅编译一次,但可以使用不同的工作组大小或网格大小多次调用)。

用Numba编写HSA内核非常类似于为CPU编写JIT函数

@roc.jit

def increment_by_one(an_array):

"""

    Increment all array elements by one.

    """

# code elided here; read further for different implementations

内核调用

通常以以下方式启动内核:

itempergroup = 32

groupperrange = (an_array.size + (itempergroup - 1)) // itempergroup

increment_by_one[groupperrange, itempergroup](an_array)

注意到两个步骤:

  • 通过指定多个工作组(或“每个网格的工作组”)和每个工作组的多个工作项来实例化内核。两者的乘积将给出启动的工作项总数。内核实例化是通过采用已编译的内核函数(在此处increment_by_one)并用整数元组对其进行索引来完成的。
  • 通过将输入数组(如果需要,以及任何单独的输出数组)传递给内核来运行内核。默认情况下,运行内核是同步的:当内核完成执行并且数据被同步时,该函数返回。

选择工作组大小

在声明内核所需的工作项数量时,具有两级层次结构似乎很奇怪。工作组的大小(即每个工作组的工作项数)通常很关键:

  • 在软件方面,工作组的大小确定了多少线程共享内存的给定区域。
  • 在硬件方面,工作组的大小必须足够大

独占执行单位。

多维工作组和网格

为了帮助处理多维数组,HSA指定多维工作组和网格。在上面的示例中,可以使itempergroupandgroupperrange元组为一个,两个或三个整数。与等效大小的一维声明相比,这不会改变所生成代码的效率或行为,但可以帮助以更自然的方式编写算法。

工作项定位

运行内核时,内核函数的代码由每个线程执行一次。因此,它必须知道它在哪个线程中,以便知道它负责哪个数组元素(复杂算法可以定义更复杂的任务,但是基本原理是相同的)。

一种方法是让线程确定其在网格和工作组中的位置,然后手动计算相应的数组位置:

@roc.jit

def increment_by_one(an_array):

# workitem id in a 1D workgroup

tx = roc.get_local_id(0)

# workgroup id in a 1D grid

ty = roc.get_group_id(0)

# workgroup size, i.e. number of workitem per workgroup

bw = roc.get_local_size(0)

# Compute flattened index inside the array

pos = tx + ty * bw

# The above is equivalent to pos = roc.get_global_id(0)

if pos < an_array.size:  # Check array boundaries

an_array[pos] += 1

注意

除非确定工作组大小和网格大小是阵列大小的除数,否则必须如上所述检查边界。

get_local_id()get_local_size()get_group_id()和 get_global_id()是由HSA后端为知道thread层次结构的几何形状和该几何形状内的当前工作项的位置的唯一目的提供特殊功能。

numba.roc.get_local_id(dim)

取得要查询的维度的索引

返回给定维度的当前工作组中的本地工作项ID。对于一维工作组,索引是一个整数,范围从0(含)到numba.roc.get_local_size()异(exclusive)。

numba.roc.get_local_sizedim

取得要查询的维度的索引

返回给定维度上工作组的大小。实例化内核时声明该值。对于给定内核中的所有工作项,该值相同,即使属于不同的工作组(即,每个工作组“已满”)也是如此。

numba.roc.get_group_iddim

取得要查询的维度的索引

在启动了内核的工作组网格中返回工作组ID。

numba.roc.get_global_iddim

取得要查询的维度的索引

返回给定维度的全局工作项ID。与numba.roc .get_local_id()不同,此数字对于网格中的所有工作项都是唯一的。

编写HSA内核的更多相关文章

  1. 编写CUDA内核

    编写CUDA内核 介绍 与用于CPU编程的传统顺序模型不同,CUDA具有执行模型.在CUDA中,编写的代码将同时由多个线程(通常成百上千个)执行.解决方案将通过定义网格,块和线程层次结构进行建模. N ...

  2. 在Ubuntu上为Android系统编写Linux内核驱动程序(老罗学习笔记1)

    这里,我们不会为真实的硬件设备编写内核驱动程序.为了方便描述为Android系统编写内核驱动程序的过程,我们使用一个虚拟的硬件设备,这个设备只有一个4字节的寄存器,它可读可写.想起我们第一次学习程序语 ...

  3. 在Ubuntu上为Android系统编写Linux内核驱动程序

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6568411 在智能手机时代,每个品牌的手机都有 ...

  4. 使用FormatMessage函数编写一个内核错误码查看器

    在编写驱动程序的时候,常用的一个结构是NTSTATUS,它来表示操作是否成功,但是对于失败的情况它的返回码过多,不可能记住所有的情况,应用层有一个GetLastError函数,根据这个函数的返回值可以 ...

  5. c++编写webui内核 .

    http://blog.csdn.net/sx1989827/article/details/8068779 #pragma once #include <mshtmhst.h> #inc ...

  6. 用JAVA编写浏览器内核之实现javascript的document对象与内置方法

    原创文章.转载请注明. 阅读本文之前,您须要对浏览器怎样载入javascript有一定了解. 当然,对java与javascript本身也须要了解. 本文首先介绍浏览器载入并执行javascript的 ...

  7. 布客&#183;ApacheCN 翻译/校对/笔记整理活动进度公告 2020.1

    注意 请贡献者查看参与方式,然后直接在 ISSUE 中认领. 翻译/校对三个文档就可以申请当负责人,我们会把你拉进合伙人群.翻译/校对五个文档的贡献者,可以申请实习证明. 请私聊片刻(52981514 ...

  8. 内核第三讲,进入ring0,以及编写第一个内核驱动程序.

    内核第三讲,进入ring0,以及编写第一个内核驱动程序. PS: 请下配置双机调试,下方有可能用到.如果不配置,则你可以不用调试, 博客连接: http://www.cnblogs.com/iBina ...

  9. linux 内核邮件列表

    第一节 - 一般性问题 1. 为什么有些时候使用“GNU/Linux"而另一些时候使用“Linux”? 答:在这个FAQ中,我们尝试使用“linux”或者“linux kernel”来表示内 ...

随机推荐

  1. Spring Cloud 微服务架构整理记录与示例首页

    ---------------------------目录-------------------------------- 一.SpringCloud系列组件实战(Eureka.Ribbon.Hyst ...

  2. Known Notation 39届亚洲赛牡丹江站K题

    题意:       题意,哎!说道题意就蛋疼啊,比赛的时候就愣是把这个题目读成数字可以随意组合,比如123 可以拆成1 23 ,12 3 ,1 2 3,结果显然,水题当神题,各种想不出来,然后就显然的 ...

  3. Python中的socket网络模块

    目录 Socket 服务端(server.py) 客户端(client.py) socket中的一些常用方法 Socket 对象(内建)方法 Python Internet 模块 Python3 提供 ...

  4. 【python】Leetcode每日一题-二叉搜索迭代器

    [python]Leetcode每日一题-二叉搜索迭代器 [题目描述] 实现一个二叉搜索树迭代器类BSTIterator ,表示一个按中序遍历二叉搜索树(BST)的迭代器: BSTIterator(T ...

  5. 【微信小程序】--bindtap参数传递,配合wx.previewImage实现多张缩略图预览

    本文为原创随笔,纯属个人理解.如有错误,欢迎指出. 如需转载请注明出处 在微信小程序中预览图片分为 a.预览本地相册中的图片. b.预览某个wxml中的多张图片. 分析:实质其实是一样的.都是给wx. ...

  6. MySQL字段默认值设置详解

    前言: 在 MySQL 中,我们可以为表字段设置默认值,在表中插入一条新记录时,如果没有为某个字段赋值,系统就会自动为这个字段插入默认值.关于默认值,有些知识还是需要了解的,本篇文章我们一起来学习下字 ...

  7. 通过CRM系统实现工作流程自动化

    灵活运用CRM系统所拥有的自动化功能模块,是公司在快速发展和降低成本的关键保障.不管您的公司规模的大小,您企业的工作流程都必须遵照相同的流程反复操作.这种反复的工作是一个效率黑洞,长久以往会导致人力资 ...

  8. 阿里云RDS数据库到期实例被清除,别急着哭(阿里没有删库跑路),或许还有一线生机

    阿里资源到期未续费,数据保存期限: ECS实例的保存期是15天. Redis实例的保存期是7天. RDS实例的保存期也是7天. 过期当天会收到一条短信: [阿里云]尊敬的用户:您的RDS实例(实例ID ...

  9. 在ActiveMQ中使用SingleConnectionFactory遇到的坑

    我们在生产环境使用了ActiveMQ作为消息中间件,消息中间件连接到数据库对消息进行持久化. 最近发生了一个奇怪的事情,消费者端的生产日志总是报如下错误: The JMS connection has ...

  10. checked 和 prop() (散列性比较少的)

    在<input  class="sex1" type="radio" checked>男 checked表示该框会被默认选上 prop()操作的是D ...