0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

在动态环境中使用CUDA图提高实际应用程序性能

星星科技指导员 来源:NVIDIA 作者:wnger 2022-04-01 16:39 次阅读

通过将计算密集型部件卸载到 GPU 上,可以大大加快许多工作负载。在 CUDA 术语中,这被称为启动内核。当这些内核很多且持续时间很短时,启动开销有时会成为一个问题。

CUDA Graphs提供了一种减少开销的方法。图形之所以有效,是因为它们将任意数量的异步 CUDA API 调用(包括内核启动)组合到一个只需要一次启动的操作中。它们在创建时确实会产生一些开销,因此它们的最大好处来自多次重用。

在 ToolkitVersion10 中引入 CUDA 图形时,可以对其进行更新,以反映其实例化中的一些细微变化。此后,此类更新操作的覆盖范围和效率显著提高。在这篇文章中,我描述了一些通过使用 CUDA 图来提高实际应用程序性能的场景,其中一些场景包括图更新功能。

上下文

考虑一个应用程序,该函数具有启动许多短运行内核的功能,例如:

poYBAGJGulWAOyPuAAAFvZpVAF8987.png

如果每次遇到此函数时都以相同的方式执行,则可以使用流捕获将其转换为 CUDA 图。在本例中,必须引入一个开关布尔值captured,以指示是否已经创建了图形。将此开关的解除 Clara 操作和初始化放在源代码中,使其范围包括对函数tight_loop的每次调用。

poYBAGJGulyAFuuRAAAF3Lw50O4800.png

接下来,用代码包装函数的任何实际调用,以创建对应的 CUDA 图(如果它不存在),然后启动该图。

pYYBAGJGumOAMi1JAAAnzvQqQS4803.png

对 tight _循环函数的调用实际上并不执行任何内核启动或其他 CUDA 操作。它只记录所有这些操作并将它们存储在数据结构中。

关注启动内核的函数。在实际应用中,它看起来像以下代码:

poYBAGJGumyASIDpAAAXe5K18Vs078.png

显然,如果函数的参数在连续调用后发生变化,那么表示 GPU 内部工作的 CUDA 图也应该发生变化。不能重复使用原始图形。但是,假设多次遇到相同的函数参数集,您至少可以通过两种不同的方式来处理这种情况:保存和识别图形或更新图形。

保存并识别 CUDA 图形

第一种方法从 C ++标准模板库中引入容器来存储参数集。每当您遇到一个新的参数集来唯一地定义函数tight_loop,请将它连同相应的可执行图形一起添加到容器中。

当您遇到容器中已经存在的参数集时,启动相应的 CUDA 图形。假设在本例中,变量first、params.size和delta唯一地定义了tight_loop。这个三胞胎是钥匙用于区分图形。您可以在源代码中定义它和要使用的容器,使其范围包括对函数tight_loop的每次调用。

poYBAGJGunaAGL_hAAAQ1ocfeD8808.png

无论函数tight_loop出现在何处,都要用填充键的代码将其包装起来,并在容器中查找。如果找到键,代码将启动相应的可执行 CUDA 图。否则,它将创建一个新图形,将其添加到容器中,然后启动它(图 1 )。

poYBAGJGuoCAM6VXAAAxtadBF_Q510.png

pYYBAGJGujWAedr8AABToxtd1Jo121.jpg

图 1 。保存和识别图形。

这种方法通常效果很好,但有一些固有的危险。在本例中,您确定只需要三个参数来定义容器中的键。对于不同的工作负载,这可能不同,或者另一个开发团队成员可能会默默地向结构中添加字段MyStruct。这会影响非平凡函数cmpKeys的编写方式。此函数是容器所必需的,用于确定某个密钥是否比另一个密钥小。

为 STL 容器编写一个非平凡的比较函数通常并不困难,但当一个键由多个非平凡的实体组成时,可能会很乏味。一种普遍适用的方法是使用词典比较。对于本例,以下代码示例有效:

poYBAGJGuoqASMg9AAASn6BEFeI556.png

更新 CUDA 图

请记住,要重用以前捕获的可执行 CUDA 图,它必须与调用上下文完全匹配:

相同拓扑

图节点的数量和类型相同

图节点之间的依赖关系相同

相同节点参数

但是,如果 CUDA 图的拓扑结构保持不变,则可以调整它以使其符合新的需要。存在一种方便的机制来确认拓扑等价性,同时调整节点参数以返回修改后的可执行图。它由cudaGraphExecUpdate提供,其工作原理是将现有的可执行图与新派生的图进行比较(例如,通过流捕获方便地获得)。如果可能,差异用于进行更改。

这种方法的好处是双重的。首先,当更新足够时,可以避免昂贵的新 CUDA 图实例化。第二,你不必知道是什么让图形独一无二。任何图形比较都由 update 函数隐式执行。下面的代码示例实现了此方法。与之前一样,它从开关的解除 Clara 和初始化开始,以指示先前创建的图形。

pYYBAGJGupaAKwZdAAA7Uhwfd7U676.png

在这个场景中,您总是执行流捕获来收集关于tight_loop中 CUDA 操作的信息。这是一个相对便宜的操作,完全在主机上执行,而不是 GPU 。它可以与以前的 CUDA 图形启动重叠,这些启动本身就是异步操作(图 2 )。

poYBAGJGujaACF1aAAA59SNfDM4913.jpg

图 2 。更新图形

一句警告的话已经准备好了。cudaGraphExecUpdate的复杂性大致与 CUDA 图形节点的更改数量成正比,因此如果大部分节点发生更改,则效率会降低。

后果

推动这两种方法以灵活方式管理 CUDA 图的应用程序有两种不同的工作负载大小,但行为有所不同(表 1 )。所有涉及的内核在单个 NVIDIA A100 GPU 上执行需要 2 – 8 微秒。报告的加速是针对代码中可以转换为 CUDA 图形的部分。

poYBAGJGup-AIHSQAAA4Mm_yIno078.png

结论

具有许多小 CUDA 内核的应用程序通常可以使用 CUDA 图进行加速,即使内核启动模式在整个应用程序中发生变化。鉴于这种动态环境,最佳方法取决于应用程序的具体情况。希望您能发现本文中描述的两个示例易于理解和实现。

审核编辑:郭婷

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • NVIDIA
    +关注

    关注

    14

    文章

    4251

    浏览量

    100411
  • gpu
    gpu
    +关注

    关注

    27

    文章

    3779

    浏览量

    125017
收藏 人收藏

    评论

    相关推荐

    XScale 应用程序性能的优化策略

    性能、低功耗特性的ARM 兼容嵌入式微处理器架构。XScale 引入了多种硬件特性提高其处理能力,但也给应用程序的优化带来了困难。本文分析XScale 体系结构的特点
    发表于 05-18 13:07 5次下载

    快速识别应用程序性能瓶颈

    应用程序性能瓶颈,从而确保使用JAVA、VISUAL C/C++和VISUAL BASIC开发的应用程序的质量和性能。RATIONAL QUANTIFY向开发团队提供了一个全面、图形化的性能数据
    发表于 04-18 22:15 20次下载

    DVFS对程序性能影响模型

    性能,而这一问题尚未被深入探索.专注于 DVFS 机制对应用程序性能的影响,提出了一个分析模型用来量化地刻画应用程序性能与处
    发表于 12-30 14:56 1次下载

    LabVIEW应用程序性能瓶颈的解决

    应用程序中的性能瓶颈。使用内置工具和VI分析器,您可以监视VIs的内存使用情况和执行时间,以确定导致应用程序性能下降的代码部分。
    发表于 03-29 14:03 8次下载
    LabVIEW<b>应用程序</b>中<b>性能</b>瓶颈的解决

    通过32Gb/S光纤通道提高应用程序性能

    提高应用程序性能.pdf》资料免费下载
    发表于 07-29 09:56 0次下载
    通过32Gb/S光纤通道<b>提高</b><b>应用程序性能</b>

    第6代光纤通道:加速全闪存数据中心的数据访问和应用程序性能

    应用程序性能.pdf》资料免费下载
    发表于 08-29 11:52 0次下载
    第6代光纤通道:加速全闪存数据中心的数据访问和<b>应用程序性能</b>

    使用Brocade Gen 7 SAN确保应用程序性能和可靠性

    应用程序性能和可靠性.pdf》资料免费下载
    发表于 09-01 10:51 0次下载
    使用Brocade Gen 7 SAN确保<b>应用程序性能</b>和可靠性

    利用矢量硬件如何提高应用程序性能

    提高应用程序性能
    的头像 发表于 05-31 11:46 890次阅读

    使用Eclipse将Android应用程序添加本机x86架构中

    应用程序中。添加支持还有可能提高应用程序性能。 本指南详细介绍了使用Eclipse开发
    的头像 发表于 11-06 06:50 2556次阅读

    了解CPI对分析程序性能的意义

    程序性能的意义。如果已经非常了解 CPI 对分析程序性能的意义,可以跳过本小节的阅读。
    的头像 发表于 12-15 10:30 8769次阅读

    如何通过多线程并发设计来提高应用程序性能

    现代多处理器或多内核环境下,如何通过多线程并发设计来提高我们应用程序性能和响应性。
    的头像 发表于 09-28 02:13 4702次阅读

    如何使用CMake工具套件构建CUDA应用程序

    CUDA 应用程序。如果您是 CMake 的现有用户,请试用 CMake 3 . 9 并利用改进的 CUDA 支持。如果您不是 CMake 的现有用户,请试用 CMake 3 . 9 ,亲身体验一下它对于构建使用 CUDA 的跨平台项目有多好。
    的头像 发表于 04-01 17:42 3235次阅读
    如何使用CMake工具套件构建<b>CUDA</b><b>应用程序</b>

    使用CUDA流顺序内存分配器助于提高现有应用程序性能

    实际应用程序中的性能影响,以下是来自 RAPIDS GPU 大数据基准 ( GPU -bdb]的结果。
    的头像 发表于 04-21 15:32 2738次阅读
    使用<b>CUDA</b>流顺序内存分配器助于<b>提高</b>现有<b>应用程序</b>的<b>性能</b>

    JavaScript中动态的创建QML对象

    实际QML应用开发中,我们可以JavaScript中动态的创建QML对象。这样做可以延迟对象的实例化,当我们需要创建对象的时候才JavaScript代码中创建,则可以缩短应用程序的启动时间,还可以动态创建可视对象,有助于
    的头像 发表于 09-01 10:42 906次阅读

    【虹科白皮书】通过卫星网络测试应用程序性能的最佳做法

    确保应用程序性能和维护良好用户体验方面。延迟、数据包丢失、链路抖动和带宽不对称等网络损害卫星网络上被放大,这可能导致应用程序速度变慢或
    的头像 发表于 03-25 10:42 175次阅读
    【虹科白皮书】通过卫星网络测试<b>应用程序性能</b>的最佳做法