《OpenACC并行程序设计:性能优化实践指南》一 2.3 描述数据移动

简介: 本节书摘来自华章出版社《OpenACC并行程序设计:性能优化实践指南》一 书中的第2章,第2.3节,作者:[美] 罗布·法伯(Rob Farber),更多章节内容可以访问云栖社区“华章计算机”公众号查看。

2.3 描述数据移动

为了确保三个加速版子程序共享了设备端数组且没有进行多余的数据移动,将引入OpenACC data导语来在较高层次的编程调用树上表达必须的数据移动。通过获得编译器对数据移动的控制能力,程序员能够知道数据实际上在程序整体中是如何利用的,而不是要求编译器仅通过数据是如何在个别函数中使用的就进行决策。
OpenACC具有两种不同类型的导语来控制设备端存储器的分配:结构化的和非结构化的。结构化方法在同一个代码作用域中(例如一个函数中)具有定义好的起始端和结束端,这限制了数据移动的结构化表示能力。非结构化数据导语给程序员提供了更大的灵活性,包括数据管理起始点、允许设备端数据分配和删除发生在程序段的不同区域中。这种功能在C++类中的作用尤为突出。数据频繁地在构造函数中创建,在析构函数中销毁。这种功能也给程序员提供了一种更为洁净的手段进行设备端数据管理,并与主机端数据管理保持一致性。因此,下面将要使用非结构化数据导语进行设备端数据的管理并进行现存代码的修改。
enter data和exit data导语用于非结构化数据管理。就像导语名称中暗示的一样,enter data表明了一个设备端变量生命周期的开始,这通常由create或copyin数据子句实现。类似的,exit data导语标记了变量生命周期的结束,由copyout、release和delete数据子句实现。因为数据在函数间进行传递,故实际上有可能同一个变量具有多个enter和exit数据导语进行修饰,因此运行时会使用一个计数器来统计该变量被引用了多少次,这能够确保数据不在有用时将会被数据端清除。运行时将利用这一引用计数器来决定是否有必要在设备端和主机端进行数据拷贝,运行时尽量确保如果有必要且有可能,仅在第一次和最后一次引用中进行数据拷贝。表2-2是表2-1的扩展,增加了两个数据子句,这两个子句仅会出现在exit data导语中。
screenshot

描述矩阵和向量的数据移动
为了避免三个加速函数中不必要的数据移动,将要添加非结构化数据导语,控制矩阵和向量结构体中的数据。OpenACC数据模型是主机优先的,这一点非常重要。这意味着在设备上进行存储分配的数据导语必须出现在主机端分配内存语句之后(如malloc, allocate, new等)。在设备上销毁数据的数据导语必须出现在主机端销毁内存语句之后(如free, deallocate, delete等)。综上,在allocate_3d_poisson_matrix和allocate_vector函数中添加enter data导语。该两函数分别位于matrix.h和vector.h头文件中。由于allocate_3d_poisson_matrix实施了一些附加初始化工作,最简单的解决方案是,在子程序的末尾添加导语,这样的话拷贝到设备端的数据结构将能够包含初始化后的数据。
图2-16是一个缩略后的具有enter data导语修饰的allocate_3d_poisson_matrix函数列表。先将A拷贝到设备中,再将所有元素进行拷贝,这种操作看起来可能较为奇怪。结构体A中包含2个标量变量和3个设备端变量指针。第71行中关于A的copyin子句拷贝了整个结构体,连同上述的5个成员。当拷贝3个指针时,可能会出现问题。因为它们可能包含了指向主机端内存的指针。原因在于这些指针只是简单地向设备进行了拷贝。此时有必要将指针指向的数据同时进行拷贝,这一操作对应于第72行导语。第72行指明了A中包含的三个数组,并且将它们包含的数据拷贝到了设备端。当从设备端销毁free_matrix函数中的数据时,这一系列操作必须以相反的顺序执行,如图2-17所示。

screenshot

allocate_vector和free_vector函数可用类似方法将Vector结构体加载到加速器中。因为allocate_vector并未对向量数据进行初始化,故可用create数据导语来进行存储器分配,避免不必要的数据拷贝,如图2-18所示。
此刻,该测试程序的所有矩阵和向量数据结构均位于设备端,但由于未对向量数据进行初始化,所得结构是不正确的。为了纠正这一问题,需要修改initialize_vector函数来使用初始化后的主机端数据对设备端数据进行更新。这里使用OpenACC的update导语实现。update导语维护主机端和设备端数据的一致性,通过在主机端和设备端互相进行拷贝来实现这一功能。在支持统一内存寻址功能的设备中,update操作将被忽略。

screenshot

update导语接收device和self子句,分别声明哪部分数据将要进行修改。如果想要更新引用自主机端的设备端数据,需要使用device子句,表明设备端数据coeffici-ents数组需要进行更新。update导语可被用于initialize_vector函数中,实现将数据从初始化的主机端向量拷贝至设备端,如图2-19所示。使用update导语时,需要更新的数据元素个数的表达方式与之前展示的data子句的用法一致。对于Fortran数组,如果需要更新的是整个数组,则边界描述可以省略。

screenshot

对于OpenACC初级程序员来说,有一点较为迷茫,即为什么更新主机端数组的子句被称为self。OpenACC 1.0标准规定使用host关键字描述主机端数组基于设备端数组进行的更新。但自从OpenACC 2.0发布以来,嵌套多个OpenACC计算区域成为了可能,存在这种可能性,进行更新操作的线程并非位于主机端,而是位于另一个设备端。图2-20展示了两个kernels区域嵌套的示例伪代码。当第4行更新操作启动时,执行外层kernels循环的设备将从A向运行第5行kenrels的设备进行数据拷贝。第8行中,运行外层kernels的设备需要将内层区域计算的结果进行取回拷贝。这里,称之为更新主机端变量是不正确的,因为第1行处的kernels区域不一定运行在主机端,因此OpenACC 2.0标准引入了update self的概念,实现基于设备端数据更新“自己”的数据副本。host关键字被2.0标准保留了下来,但它的含义已经等同于self关键字了。
此时,编译运行测试代码,将看到计算性能获得了极大的提升。检查PGProf时间线(图2-21),发现数据在程序最开始进行了拷贝,计算结果仅在计算完成后进行周期性拷贝。这是因为已经通知编译器,数据可以直接在加速器上分配存储空间,此外,前文添加的计算区域检测数据变量的存在性,之后确认数据存在于设备端,利用现存的变量进行计算。在具有独立存储器的加速器上,比如本例中使用的GPU,数据移动的恰当安排是程序员能够获得最大性能提升的部分。这是由于它能够有效移除PCIe总线数据传输缓慢这一最大性能瓶颈。因为这一项工作通常能提供最大的性能提升,故它在程序开发中的优先级最高。但是,这一任务的实施容易导致错误。因此,有必要在每次遇到未加速循环时引入update导语进行更新。更为简单的处理方式是,将所有的循环加载到设备上,或至少是一些关键代码段,然后移除不必要的数据移动。忘记消除不必要的数据移动是常见性能损失的来源,这些问题易于通过性能分析器发现。而过于频繁地添加data导语却忘记添加update导语是个错误,通常更难发现。

screenshot

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
相关文章
|
JavaScript 前端开发
JS如何处理后台时间
JS如何处理后台时间
246 58
|
3天前
|
人工智能 自然语言处理 JavaScript
2026年Windows+Ollama本地部署OpenClaw保姆级教程:本地AI Agent+阿里云上快速搭建
2026年OpenClaw凭借本地部署、私有化运行的特性,成为打造个人智能体的核心工具,而Ollama作为轻量级本地大模型管理工具,能让OpenClaw摆脱对云端大模型的依赖,实现**本地推理、数据不泄露、全流程私有化**的智能体验。本文基于Windows 11系统,从硬件环境准备、Ollama安装与模型定制、OpenClaw部署配置、技能扩展到常见问题排查,打造保姆级本地部署教程,同时补充阿里云OpenClaw(Clawdbot)快速部署步骤,兼顾本地私有化需求与云端7×24小时运行需求,文中所有代码命令均可直接复制执行,确保零基础用户也能快速搭建属于自己的本地智能体。
5155 27
|
10天前
|
存储 人工智能 负载均衡
阿里云OpenClaw多Agent实战宝典:从极速部署到AI团队搭建,一个人=一支高效军团
在AI自动化时代,单一Agent的“全能模式”早已无法满足复杂任务需求——记忆臃肿导致响应迟缓、上下文污染引发逻辑冲突、无关信息加载造成Token浪费,这些痛点让OpenClaw的潜力大打折扣。而多Agent架构的出现,彻底改变了这一现状:通过“单Gateway+多分身”模式,让一个Bot在不同场景下切换独立“大脑”,如同组建一支分工明确的AI团队,实现创意、写作、编码、数据分析等任务的高效协同。
4177 29
|
14天前
|
人工智能 自然语言处理 监控
OpenClaw skills重构量化交易逻辑:部署+AI全自动炒股指南(2026终极版)
2026年,AI Agent领域最震撼的突破来自OpenClaw(原Clawdbot)——这个能自主规划、执行任务的智能体,用50美元启动资金创造了48小时滚雪球至2980美元的奇迹,收益率高达5860%。其核心逻辑堪称教科书级:每10分钟扫描Polymarket近千个预测市场,借助Claude API深度推理,交叉验证NOAA天气数据、体育伤病报告、加密货币链上情绪等多维度信息,捕捉8%以上的定价偏差,再通过凯利准则将单仓位严格控制在总资金6%以内,实现低风险高频套利。
7631 66
|
4天前
|
人工智能 JSON JavaScript
手把手教你用 OpenClaw + 飞书,打造专属 AI 机器人
手把手教你用 OpenClaw(v2026.2.22-2)+ 飞书,10分钟零代码搭建专属AI机器人!内置飞书插件,无需额外安装;支持Claude等主流模型,命令行一键配置。告别复杂开发,像聊同事一样自然对话。
2062 6
手把手教你用 OpenClaw + 飞书,打造专属 AI 机器人
|
4天前
|
人工智能 运维 安全
OpenClaw极速部署:ZeroNews 远程管理OpenClaw Gateway Dashboard指南+常见错误解决
OpenClaw作为高性能AI智能体网关平台,其Gateway Dashboard是管理模型调用、渠道集成、技能插件的核心操作界面,但默认仅支持本地局域网访问。官方推荐的Tailscale、VPN等远程访问方案在国内网络环境中体验不佳,而ZeroNews凭借轻量化部署、专属域名映射、多重安全防护的特性,成为适配国内网络的最优远程管理解决方案。
1473 2
|
5天前
|
存储 人工智能 BI
2026年OpenClaw(Clawdbot)极简部署:接入小红书全自动运营,一个人=一支团队
2026年的小红书运营赛道,AI自动化工具已成为核心竞争力。OpenClaw(原Clawdbot)凭借“Skill插件化集成、全流程自动化、跨平台联动”的核心优势,彻底颠覆传统运营模式——从热点追踪、文案创作、封面设计到自动发布、账号互动,仅需一句自然语言指令,即可实现全链路闭环。而阿里云作为OpenClaw官方推荐的云端部署载体,2026年推出专属秒级部署方案,预装全套运行环境与小红书运营插件,让零基础用户也能10分钟完成部署,轻松拥有7×24小时在线的“专属运营团队”。
1614 7
|
9天前
|
人工智能 自然语言处理 安全
2026年OpenClaw Skills安装指南:Top20必装清单+阿里云上部署实操(附代码命令)
OpenClaw(原Clawdbot)的强大之处,不仅在于其开源免费的AI执行引擎核心,更在于其庞大的Skills生态——截至2026年2月,官方技能市场ClawHub已收录1700+各类技能插件,覆盖办公自动化、智能交互、生活服务等全场景。但对新手而言,面对海量技能往往无从下手,盲目安装不仅导致功能冗余,还可能引发权限冲突与安全风险。
2383 9
|
1月前
|
人工智能 自然语言处理 Shell
🦞 如何在 OpenClaw (Clawdbot/Moltbot) 配置阿里云百炼 API
本教程指导用户在开源AI助手Clawdbot中集成阿里云百炼API,涵盖安装Clawdbot、获取百炼API Key、配置环境变量与模型参数、验证调用等完整流程,支持Qwen3-max thinking (Qwen3-Max-2026-01-23)/Qwen - Plus等主流模型,助力本地化智能自动化。
47092 160
🦞 如何在 OpenClaw (Clawdbot/Moltbot) 配置阿里云百炼 API

热门文章

最新文章