第5章 HSA内存模型

news2024/11/18 7:48:06

5.1 引言

在共享内存环境中,独立的控制线程可以竞相修改单个位置。为程序以可预测的方式运行,程序员必须用同步来控制这些竞争。

“内存一致性模型”或“内存模型”定义了并行代理之间通信的基本规则。当这些规则含糊不清地定义或者更糟的是完全不存在的时候,困难的任务变得更加困难。事实上,如果没有明确定义的内存模型,编写正确的、可移植的代码通常是不可能的。

直到2011年,C和C++才有定义明确的内存模型。在此之前,实现依赖于编译器的特定操作或者甚至特定于目标的操作来对内存进行排序。因此,编写可移植代码非常困难。

早期的异构编程模型也采取了类似的路径;第一个可用的可用的平台没有指定一个内存模型。早期的采用者不得不依靠语言和硬件实现的知识来创建代理间通信的代码。

5.2 HSA内存结构

所有编写其他异构编程模型的人都希望HSA的内存组织能够高效地支持GPU。它旨在使高性能算法能够以最少的通信量高效运行,而不会产生不必要的硬件成本或复杂性,同时为更苛刻的算法提供强大的内存排序保证。

HSA内存组织可以被看作在单个地址空间内排列的一组内存区域。每个区域的重要性能和性质略有不同。硬件和工具相结合使得有效地将应用程序映射到可用的目标硬件范围。另外,多个段可以使用相同的地址范围但是地址完全分开的物理内存位置。编译器根据它生成的访问位置的指令区分这些段和物理地址。

5.2.1 分段

HSA内存的概念分布在7个不同的段。HSA中可用的段是:全局(单个网格上运行的所有工作项)、组(工作组)、私有(工作项)、只读、溢出、内核参数和参数。前4者通常由程序员直接控制。只读区域是因为一些设备能够使用专门的常量缓冲区以比一般缓存机制更高的性能或更低的功耗访问只读内存。通过将这个地址空间作为核心HSA特性公开,编译器可以生成特殊的指令来有效地完成这个任务。

后3者内存段支持定义编译为HSAIL的HSA程序的底层API。内核参数内存代表了内核参数的集合,执行时视其为只读,并可能由运行时复制到单独的常量内存,以使它们高效可见地调度所有工作项。溢出内存是高级编译器可以通过它分配到HSAIL寄存器并与终止器通信的任何寄存器,它不能或不想分配为HSAIL寄存器,这样内存不会泄露。终止器可以区分表示注册表溢出(即不在工作项之间共享的暂态内存操作)以及可能共享或具有较长生命周期的其他内存操作,以优化结果代码。溢出内存通过HSA运行时不可见。出于内存分配的目的,它被分类为私有内存。参数内存表示用于将函数参数传递到调用函数的位置。参数内存与终止器通信,该位置的生命周期特定于调用/返回过程过程,因此允许以各种方式进行分配,这取决于设备的基础ABI。这与内核参数内存不同,在内核执行过程中,位置是活的。

5.2.2 平面寻址

为了便于使用,并且使高级语言的编译过程变得更加简单,HSAIL的输入不会不会使地址空间显式化,HSA内存模型支持平面地址空间。平面地址空间允许通过地址空间中的实现定义的划分区域来寻址全局、组和私有地址空间中的所有位置。高级语言中的指针可以重用以映射到不同的段。

HSAIL代码中任何给定的操作都明确指出它的源地址空间是什么。如果操作从平面地址空间获取数据,则终止器生成转换操作或硬件必须检查在那个子范围内以及是否是组或私有位置。如果值非空,操作或硬件必须通过减去值不为null的段偏移量重定向到该段,或者如果该值为空,则转换为特定的空值。

5.2.3 共享虚拟寻址

HSA设计的核心功能是共享虚拟内存。共享虚拟内存最基本的部分是在设备之间共享虚拟地址的能力。所有HSA设备和主机进程都需要能够通过内存传递地址。这些地址必须由系统中的所有设备以相同的方式解释。这使得应用程序的可移植性、灵活性和数据结构实现的简单些成为可能。通过避免副本和布局变化,它也提高了效率。

共享虚拟地址允许包含指针的数据结构在HSA设备之间传递。它还允许将指针存储在内存中,而不需要将其缓冲区偏移量。

共享虚拟地址不一定需要内存一致性。然而,从包含指针的数据结结构到包含可以直接更新指针的数据结构的转换是下一节的一小步。这一步使修改立即对其他设备可见。

即使没有一致性,共享虚拟地址也会导致性能上的好处。在较早的系统中,如果不能在设备之间使用相同的虚拟地址,内存可能会在传递到设备时改变地址。主CPU上的内存分配将被复制到GPU的分立内存中。物理位置不仅会改变,而且所指的虚拟地址范围也会改变。指向这个分配中的位置的任何存储的指针将不再有效。

要解决这个问题,指针在单个内存分配中被转换为偏移量。由此产生的基地+偏移地址方案只能轻易地指向一个单一的分配。这意味着应用程序的重大重构以及可能大量的运行时数据重排对于数据结构按照在主机和加速器设备上有效的形式管理是必要的。共享虚拟地址允许代码变得更简单,需要更少的数据转换。

HSA设备的地址空间与主机的地址空间相匹配。另外,虚拟地址空间的一部分由HSA系统软件划分出来,以将平面地址表示成HSA设备上的私有或组内存。虚拟内存还必须满足通常的保护机制,以确保数据与不同进程的分离。

5.2.4 所有权

HSA运行时控制的分配中的一些可以以粗粒度的形式分配。粗粒度分配时共享虚拟寻址的内存分配,但不要求一致性。它们的存在主要有2个原因:
        1. 即使在共享虚拟内存和完全控制内存一致性的世界中,离散加速器依然存在。在这样的设备上,使每一个设备一致的操作可能会非常昂贵,因为设备可以通过非常低的带宽或高延迟互联连接到主机。
        2. 其次时降低功耗。预计HSA将得到众多设备的支持。在功耗非常低的设备上,即使是片上加速器,内存一致性也变得非常昂贵。细粒度内存一致性系统的额外探测或缓存刷新流量会消耗功率。

为了支持这些优化,粗粒度内存允许在一段时间内将一致性限制在特定的设备上。我们称之为边界所有权。HSA运行时API调用为驱动程序控制提供了更新虚拟内存系统、关闭页面级别的一致性、将数据迁移到新的物理位置以及更新虚拟内存映射或其组合的机会。当地址范围由给定设备拥有时,其内存一致性属性会改变。

5.3 HSA内存一致性基础

程序和系统之间的约定显示了如何编写正确的HSA程序,如何实现正确的终止器优化,以及如何构建正确的符合HSA标准的硬件。

HSA内存一致性模型由2个同样有效的视图。首先,有一个简单的观点,即只考虑HSA程序的“顺序一致”执行。其次,还可以将内存一致性模型视为执行中的部分命令的复杂组合。HSA松弛原子操作可以在有限的情况下提高性能或减少执行能量。

5.3.1 背景:顺序一致性

大多数内存一致性模型(包括HSA)在单个执行单元、线程或代理内保留顺序语义。如果内存操作O1(加载、存储或读取-修改-写入)发生在内存操作O2之前,则O1的作用对O2是可见的。然而,内存模型在它们如何允许来自不同执行单元的内存操作相互交错方面差别很大。最直观的模型是顺序一致性。

顺序一致性保证了在任何有效的执行过程中都有一个全局可观察的加载、内存和读取-修改-写入的交错。得此名称是因为整个程序看起来好像是一个简单的顺序处理器,可以在多个可用线程之间进行多任务处理。

但是顺序一致性模型可能会限制硬件或编译器可以执行的优化。例如,合并存储操作的硬件写入缓冲区(图形处理器中常见的组件)可能会导致不连续一致性的结果。由于局限性,大多数平台(包括罗=HSA)都指定了一个比顺序一致性弱的模型。

5.3.2 背景:冲突和竞争

当读写冲突已经同步时(例如,它们出现在受锁定保护的关键部分中),就会发生“内存竞争”。内存竞争通常是良性的,因为同步将确保它们始终以正确的顺序执行。当读写冲突没有被同步,并且不是同步原语的一部分时,就会发生数据竞争。数据竞争在程序中通常是有害且无意的,因为它们导致不可预知的行为。

5.3.3 单一内存范围的HSA内存模型

任何无数据竞争的HSA程序的执行将出现顺序一致。此外,任何HSA程序的执行都是不确定的。

由于内存模型只定义了无数据竞争的HSA程序的行为,因此我们必须能够精确地定义数据竞争来编写编写正确的程序。为了避免数据竞争,我们必须确保一个程序有足够的同步。为了基本理解,如果在观察到的顺序一致的操作顺序中的冲突操作之间出现HSA同步,则可以说顺序一致的执行中的冲突是同步的。

1. HSA同步操作

在HSA中,通过原子内存操作进行同步。HSA原子是加载、存储或读取-修改-写入,被定义为具有特定语义的、内存范围和段的原子类型。

HSA原子可以释放、获取或获取-释放语义。所有的原子都有副作用,影响与原子相同的指令流中的其他指令如何出现在其他线程中。

通常,具有释放语义的原子可以确保在原子完成之前,原子之前的任何操作对其他线程都是可见的。换句话说,释放可以防止程序顺序中的原子之前的早期操作在原子之后重新排序。

获取与释放相反--具有获取语义的原子确保在原子完成前,原子之后的任何操作对其他线程都可见。获取阻止在程序顺序中的原子在原子之前重新排序之后的后续操作。

为了同步来自两个代理的普通操作,具有释放语义的原子必须被具有获取语义的原子观察到。

2. 通过不同的地址进行传递式同步

HSA中的同步是传递式的。如果A与B同步并且B与C同步,则A被认为与C同步。

3. 寻找竞争

通过确定发生冲突的程序区域来管理问题,然后确保这些冲突始终保持同步。

5.3.4 多个内存范围的HSA内存模型

每个HSA原子操作都指定一个范围。该范围将原子操作及其副作用的可见性限制为系统中工作项或主机线程的子集。

1. 范围动机

传统上,共享内存CPU系统专为低延迟、全通信而设计。这样的系统实现一致性协议,确保来自执行单元的更新自动传播到系统中的所有其他工作项或主机线程。因此,同步是轻量级的。

但是,HSA瞄准的GPU和其他设备都是为了吞吐量而设计的。GPU的许多实现都没有CPU风格的一致性协议,因为它相信这会降低吞吐量。相反,这些设备通过重量级缓存维护操作(如刷新和无效)进行同步。

如果系统不知道那些角色正在进行同步,则必须假定最坏的情况,并刷新无效所有可能持有陈旧数据的缓存。但是,如果同步实体在系统中执行的位置,系统可以减少维护操作的数量。

内存范围的具体实现将有所不同,但一般来说,同步HSA执行层次结构中彼此较为接近的工作项或主机线程的成本较低。同一工作组的两个工作项的同步要比不同工作组的工作项的要快。前者可能只涉及小内部缓冲区的刷新,类似于CPU同步,而后者可能至少涉及L1缓存的刷新和无效。

2. HSA范围

原子的范围是程序员的一个指示,原子只能被执行中的工作项或主机线程的子集观察到。为了获得良好的性能和功耗,HSA程序应该规定最小的可能范围。如果程序员指定的范围小于执行期间实际观察原子或副作用的工作项或线程集合,则该程序将包含数据竞争。

HSA定义了五个范围:工作项、波前、工作组、代理和系统。

3. 使用较小的范围

随着范围的增加,程序员面临着与原子操作同步使用的是哪个范围的附加选择。为了获得最佳性能,应该努力使用仍然导致无竞争执行的最小范围。

为了避免直接范围同步的竞争(同步的所有原子都指定相同的范围),原子的指定范围实例应包含参与同步的所有工作项和主机线程。

由于所有原子指定相同的范围实例的限制,在HSA目标的前瞻性系统中可能会受到限制。因此,HSA提供了两种无竞争方式来使用指定不同范围实例的原子。第一个称为“包含范围式同步”,第二个称为“传递式范围同步”。

(1)范围包含:只要每个原子指定包含两个同步操作的范围实例,工作项或线程就可以通过原子进行同步,而不会导致竞争。当两个范围实例不相同时,称之为范围包含。它命名的原因是:如果两个范围实例不是同一个,那么由于HSA定义的范围实例的严格层次结构,必须包含另一个范围实例。

(2)范围传递

即使工作项或线程在非包含范围实例中使用原子,也可以在不引起竞争的情况下进行同步。

5.3.5 内存段

原子释放-获取将对同步共享虚拟内存中的所有内存段,而不管原子位于何处。

5.3.6 汇总:HSA竞争自由

1. HSA竞争自由的简化定义

有两条经验法则可以帮助简化HSA竞争自由分析:
        1. 始终将相同的范围 应用于原子变量(例如,不要在原子A上执行工作组范围释放后再A上执行系统范围内获取)。
        2. 从包含所有直接涉及同步的执行单元(即忽略传递性)的最小范围实例中获取/释放。

2. HSA竞争自由的一般定义

在HSA中,冲突既可以是普通的,也可以是原子的:

        1. 普通冲突描述了对同一位置的两个操作。至少有一个是写或读取-修改-写入,且至少有一个是普通操作。
        2. 原子冲突描述了从不同执行单元到相同位置的两个原子操作。至少有一个是写或读取-修改-写入,它们指定非包含范围实例。

当且仅当所有的冲突都被包含原子同步的传递链分开,HSA程序的顺序一致的执行是无竞争的。当且仅当程序的所有顺序一致性的执行都是无竞争的,HSA程序总体上是无竞争的。

5.3.7 附加观察和注意事项

在HSA中,原子操作不能部分重叠。例如,如果32位原子操作在一个执行单元中写入地址A,而在另一个执行单元中从地址A读取64位原子,则这是HSA中的竞争。对于普通的内存操作,允许部分重叠。

请注意,与同构CPU无竞争模型不同的是,如果冲突由原子分离,则简单地说执行没有竞争是不够的。相反,这些原子也必须正确使用范围(即指定包含范围实例)。

5.4 HSA内存模型中的高级一致性

HSA内存模型进一步扩展了基本的顺序一致的无竞争模型。首先是添加松弛原子和栅栏。它支持粗粒度的内存区域,可能会限制一致性。

5.4.1 松弛原子

HSA内存模型还定义松弛原子核栅栏。松弛原子在两个方面不同于其他原子。首先,松弛原子没有同步的副作用。换句话说,它们不能强迫系统中普通加载或内存的可见性。其次,松弛原子不能保证顺序一致,即使相互之间也是如此,使得松弛原子特别难以推理。

在程序需要读取-修改-写入语义但不尝试同步工作项或线程的情况下,松弛原子是非常有用的。

松弛原子也可以来建立线程之间的因果关系。导致HSA的基本顺序一致的视图不再有效。优点在于可以以相对较低的成本重复执行松弛加载,而对系统上所有内存访问进行排序可能成本显著较高。

为了确保正确性,用户必须通过一系列必须存在任何无竞争HSA执行中的操作命令来推理程序的行为。有两个特别值得注意的命令:

        1. 所有加载、存储以及读取-修改-写入更新的总体一致顺序均位于单个位置。
        2. 释放、获取和获取-释放原子的顺序总是一致的。

从这些命令中,用户必须推断正式的“发生之前”的关系,以确定在HSA执行竞争中是否有两个冲突的操作。

松弛原子不用步普通的加载和存储。在使用松弛原子的程序中,必须添加栅栏操作来建立松弛原子操作和普通的加载和存储之间的排序关系。事实上,当把一个松弛原子和一个栅栏当做一个简单的对使用时,可以把它们看做一个标准原子的两个部分。松弛原子对应于在单个变量上云霄的标准原子的部分。栅栏对应于同步普通加载和存储的标准原子的副作用。与原子不同,栅栏不与任何特定位置相关联。

通过查分松弛原子和栅栏,程序员可以独立确定因果关系并强制同步。

虽然正常的操作只能阻止在一个方向上穿过栅栏,但它们可以朝另一个方向移动。例如,它们可以通过释放栅栏向上移动,但不能向下移动。松弛原子无法通过栅栏在任何方向移动。

5.4.2 所有权和范围界限

所有权是一种标记为粗粒度的内存区域可以在所有权期限内传递给给定代理人供该组件使用的方法。

这在两个方面与模型的其余部分一起使用:

        1. 所属区域内的系统范围原子操作隐式降级为设备范围;
        2. 访问不属于自己的可寻址范围是一次竞争。

然而,由于范围传递性,单独限制原子操作的范围并不能保证所需的语义。还必须限制原子排序的可见性副作用。

任何对无主内存区域的访问都不是由所有者访问,而是由所有权传输本身进行。任何访问该区域内未被释放或获取同步的位置都是一次竞争。

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

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

相关文章

OpenHarmony教程指南—Ability的启动模式

介绍 本示例展示了在一个Stage模型中,实现standard、singleton、specified多种模式场景。 本实例参考开发指南 。 本实例需要使用aa工具 查看应用Ability 模式信息。 效果预览 使用说明 1、standard模式: 1)进入首页,点击番茄…

Linux ubuntu 写c语言Hello world

文章目录 创建hello.c 文件进入hello.c 文件使用vim 编辑器进行编辑下载gcc 编辑器调用gcc 进行编译hello.c 创建hello.c 文件 touch hello.c进入hello.c 文件 vi hello.c使用vim 编辑器进行编辑 下载gcc 编辑器 sudo apt update sudo apt install gcc第一个语句是更新&am…

政安晨:【深度学习处理实践】(二)—— 最大汇聚运算

最大汇聚运算(Max Pooling Operation)是深度学习领域卷积神经网络常用的一种汇聚运算方式。在卷积神经网络中,经过一系列卷积层和激活函数层后,数据在空间尺寸上逐渐减小,特征图的深度也逐渐增加。为了降低数据尺寸并提…

『python爬虫』requests实战-comicai绘画ai通过cookie签到(保姆级图文)

目录 实现效果实现思路登录查询积分数量签到 实现代码总结 欢迎关注 『python爬虫』 专栏,持续更新中 欢迎关注 『python爬虫』 专栏,持续更新中 实现效果 实现思路 登录 f12 打开控制台,进入网络清除所有信息后点击登录按钮 通过搜索login(通用写法)…

Spring Boot中实现图片上传功能的两种策略

🌟 前言 欢迎来到我的技术小宇宙!🌌 这里不仅是我记录技术点滴的后花园,也是我分享学习心得和项目经验的乐园。📚 无论你是技术小白还是资深大牛,这里总有一些内容能触动你的好奇心。🔍 &#x…

学习Java的第二天

如何使用文本文档在cmd里打印出HelloWorld 1、创建一个文本文档,并命名为HelloWorld,将后缀改为java(需要自己去把后缀打开显示出来) 2、打开编辑 也可以双击打开 3、在里面写出以下代码 上面红框里为你要打印的语句,…

英伟达板子4----存储满了系统黑屏

记录一个bug,因为最近在做边缘端视频处理的内容,就把视频存储在边端设备,但是发现由于边缘端设备的存储太小了,导致把ubuntu端的存储(只有28个Gib)给吃满了。 然后搜了一篇博客说重启就能释放一些空间&…

KONG - API转发流程梳理

kong简介 Kong 是一个开源的API网关,集成了服务注册和发现、负载均衡、健康检查等功能,还可以通过插件来提供限流、熔断、监控、日志等能力, 在kong的微服务架构中,kong担当了注册中心的角色,服务提供者(Provider)首…

【b站咸虾米】ES6 Promise的用法,ES7 async/await异步处理同步化,异步处理进化史

课程地址:【ES6 Promise的用法,ES7 async/await异步处理同步化,异步处理进化史】 https://www.bilibili.com/video/BV1XW4y1v7Md/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 图文地址:https://www.b…

Java 集合类的高级特性介绍

在 Java 编程中,了解集合类的高级特性对于编写高效和可维护的代码至关重要。以下是一些你应该知道的 Java 集合类的高级特性,以及简单的例子来说明它们的用法。 1. 迭代器(Iterators)和列表迭代器(ListIterators&#…

算法归纳【数组篇】

目录 二分查找1. 前提条件:2. 二分查找边界 2.移除元素有序数组的平方长度最小的子数组59.螺旋矩阵II54. 螺旋矩阵 二分查找 参考链接 https://programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html#%E6%80%9D%E8%B7%AF 1. 前提条件: 数…

git revert 撤回之前的几个指定的提交

文章目录 Intro操作命令-n 选项 参考 Intro 在开发过程中,有的时候一开始只是一个小需求,可以改着改着事情超出了控制,比如说我一开始只是想调整一个依赖包的版本,可是改到后来类库不兼容甚至导致项目无法启动。 这个时候我就想&…

华为OD机试 - 服务器广播 - 矩阵(Java 2024 C卷 200分)

目录 专栏导读一、题目描述二、输入描述三、输出描述1、输入2、输出3、说明 四、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2024C卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试(JAVA)真题(A卷…

从数据到智能:探讨大数据在AI领域的核心作用

前言 大数据和人工智能已经成为当今社会的两大热门话题。它们之间究竟有何关系?又如何在各个领域发挥着重要作用? 概念区别与联系 一、大数据与人工智能的基本概念 大数据,顾名思义,指的是海量的、类型繁多的数据集合。这些数据…

万界星空科技MES系统中的车间管理的作用

在了解mes生产管理系统的作用包括哪些方面之前,我们先来了解一下作为生产管理信息化的关键部分,车间管理系统包含哪几个部分:一、mes系统中的车间管理通常包含以下部分: 1、设备管理:用于监控车间内的设备状态&#xf…

【日常聊聊】2024 年 AI 辅助研发趋势

🍎个人博客:个人主页 🏆个人专栏:日常聊聊 ⛳️ 功不唐捐,玉汝于成 目录 前言 正文 方向一:AI辅助研发的技术进展 方向二:行业应用案例 方向三: 面临的挑战与机遇 方向四&a…

学习人工智能:吴恩达《AI for everyone》2019 第3周:实现智能音箱和自动驾驶的几个步骤;无监督学习;增强学习

吴恩达 Andrew Ng, 斯坦福大学前教授,Google Brain项目发起人、领导者。 Coursera 的联合创始人和联合主席,在 Coursera 上有十万用户的《机器学习》课程;斯坦福大学计算机科学前教授。百度前副总裁、前首席科学家;谷…

【深度优先】【图论】【C++算法】2045. 到达目的地的第二短时间

作者推荐 视频算法专题 LeetCode2045. 到达目的地的第二短时间 城市用一个 双向连通 图表示,图中有 n 个节点,从 1 到 n 编号(包含 1 和 n)。图中的边用一个二维整数数组 edges 表示,其中每个 edges[i] [ui, vi] 表…

开源分子对接程序rDock使用方法(1)-Docking in 3 steps

欢迎浏览我的CSND博客! Blockbuater_drug …点击进入 文章目录 前言一、Docking in 3 steps 标准对接rDock 的基本对接步骤及注意事项 二、 三步对接案例Step 1. 结构文件准备Step 2. 产生对接位点Step 3. 运行分子对接3.1 检查输入文件3.2 测试-只进行打分3.3 运行…

Linux/Validation

Enumeration nmap 第一次扫描发现系统对外开放了22,80,4566和8080端口,端口详细信息如下 系统对外开放了4个端口,从nmap的结果来看,8080无法访问,手动尝试后4566也无法访问,只能从80端口开始 …