存在寄存器溢出机制时,为什么会因为寄存器使用过多而无法启动内核呢?

2023-12-13

1) 内核什么时候开始将寄存器溢出到本地内存?

2)当没有足够的寄存器时,CUDA运行时如何决定不启动内核并抛出太多资源请求错误?多少个寄存器足以启动内核?

3)既然存在寄存器溢出机制,即使没有足够的寄存器,难道不应该启动所有CUDA内核吗?


1) 内核什么时候开始将寄存器溢出到本地内存?

这完全在编译器的控制之下。它不是由运行时执行的,并且没有关于它的动态运行时决策。当您的代码达到溢出点时,这意味着编译器已插入如下指令:

STL  [R0], R1

在这种情况下,R1被存储到本地内存,本地内存地址给出R0。这将是一个溢出商店。 (在那条指令之后,R1当然,编译器知道它何时完成此操作,因此它可以报告它选择使用/制作的溢出加载和溢出存储的数量。您可以使用以下方式获取此信息(以及寄存器使用情况和其他信息):-Xptxas=-v编译器开关。

编译器(除非您对其进行限制,请参见下文)对寄存器使用做出的决定主要关注性能,否则较少关注实际使用了多少寄存器。第一要务是性能。

2)当没有足够的寄存器时,CUDA运行时如何决定不启动内核并抛出太多资源请求错误?多少个寄存器足以启动内核?

在编译时,当编译内核代码时,编译器不知道它将如何启动。它不知道您的启动配置是什么样的(块数、每个块的线程数、动态分配的共享内存量等)。事实上,编译过程大部分都在进行,就好像正在编译的东西是单个线程一样。

在编译期间,编译器会做出一系列有关寄存器分配的静态决策(如何以及在何处使用寄存器)。 CUDA有二进制实用程序这有助于理解这一点。寄存器分配在运行时不会改变,也不是动态的,因此完全在编译时确定。因此,在完成给定设备代码函数的编译时,通常可以确定需要多少个寄存器。编译器将此信息包含在二进制编译对象中。

在运行时,在内核启动时,CUDA 运行时现在知道:

  • 给定内核需要多少个寄存器(每个线程)
  • 我们在什么设备上运行,因此总限制是多少
  • 启动配置是什么(块、线程)

组合这 3 条信息意味着运行时可以立即知道是否有或将有足够的“寄存器空间”用于启动。粗略地说,通过/失败算术是发射是否满足以下不等式:

 registers_per_thread*threads_per_block <= max_registers_per_multiprocessor

该等式中还需要考虑粒度。运行时寄存器通常以 2 或 4 为一组进行分配,即registers_per_thread在应用不等式检验之前,数量可能需要向上舍入到下一个整数倍(例如 2 或 4)。这registers_per_thread如前所述,数量由编译器确定。这threads_per_block数量来自您的内核启动配置。这max_registers_per_multiprocessor数量是机器可读的(即它是您正在运行的 GPU 的函数)。如果您愿意,您可以通过研究如何自行检索该数量deviceQueryCUDA 示例代码。

3)既然存在寄存器溢出机制,即使没有足够的寄存器,难道不应该启动所有CUDA内核吗?

我重申,寄存器分配(和寄存器溢出决策)完全是一个静态编译时过程。不进行运行时决策或更改。寄存器分配完全可以从编译的代码中检查。因此,由于无法在运行时进行调整,因此无法进行任何更改以允许任意启动。任何此类更改都需要重新编译代码。虽然这在理论上是可能的,但目前尚未在 CUDA 中实现。此外,它有可能导致可变且可能不可预测的行为(在性能方面),因此可能有理由不这样做。

通过适当限制编译器对寄存器分配的选择,可以使所有内核“可启动”(相对于寄存器限制)。__launch_bounds__编译器开关 -maxrregcount有几种方法可以实现这一目标。 CUDA 提供了占用计算器以及一个占用API来帮助完成这个过程。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

存在寄存器溢出机制时,为什么会因为寄存器使用过多而无法启动内核呢? 的相关文章

  • 设备内存刷新cuda

    我正在运行一个 C 程序 其中调用了两次 cuda 主机函数 我想清理这两个调用之间的设备内存 有没有办法可以刷新 GPU 设备内存 我使用的是计算能力为2 0的Tesla M2050 如果你只想将内存归零 那么cudaMemset可能是最
  • CUDA Thrust 库中counting_iterators 的用途和用法

    我很难理解counting iterator在 CUDA 的推力库中 它的目的是什么以及如何使用 它在其他编程语言 例如 C 中也可用吗 计数迭代器只是一个迭代器 它从每次迭代器递增时前进的序列中返回下一个值 最简单的例子是这样的 incl
  • Cuda:最小二乘求解,速度较差

    最近 我使用Cuda编写了一个名为 正交匹配追踪 的算法 在我丑陋的 Cuda 代码中 整个迭代需要 60 秒 而 Eigen lib 只需 3 秒 在我的代码中 矩阵 A 是 640 1024 y 是 640 1 在每一步中 我从 A 中
  • 编程环境中的虚拟地址空间

    我对虚拟地址空间的含义感到困惑 在 32 位机器中 进程可以寻址 2 32 个内存位置 这是否意味着每个进程的虚拟地址空间是 2 32 4GB 以下是进程虚拟地址空间的快照 这个可以增长到4GB吗 这样的系统中进程数量有限制吗 这个可以增长
  • 在 Postgres 中为特定查询设置 work_mem

    我正在使用一个委托给 JDBC 驱动程序的库PostgreSQL 而且有些查询非常复杂 需要更多内存 我不想设置work mem对于所有查询来说都是大的 只是这个子集 问题是执行以下代码会导致错误 pseudo code for what
  • 一些涉及类析构函数和删除运算符的内存管理问题?

    在阅读了一些教程后 我仍然不清楚 C 中内存管理的一些观点 1 当使用 new 运算符声明的类超出范围时 是否会调用其析构函数并释放内存 是否有必要调用删除运算符来释放类的内存并调用其析构函数 class Test void newTest
  • 使用 Cuda 并行读取多个文本文件

    我想使用 CUDA 在多个文件中并行搜索给定字符串 我计划使用 pfac 库来搜索给定的字符串 问题是如何并行访问多个文件 示例 我们有一个包含 1000 个文件的文件夹 需要搜索 这里的问题是我应该如何访问给定文件夹中的多个文件 应该动态
  • 如何从内存转储中查找预加载系统绘图(位图)的 ID 或名称

    我正在分析我们应用程序的内存使用情况 发现很奇怪Drawables 它不断地 吃掉 几兆字节的堆 以下是一些截图MAT http www eclipse org mat Dominator tree with 2 pretty big bi
  • 跨 dll 边界的内存分配和释放

    我知道在一个 dll 中进行内存分配然后在另一个 dll 中释放内存可能会导致各种问题 尤其是与 CRT 相关的问题 当涉及到导出 STL 容器时 此类问题尤其成问题 我们之前遇到过此类问题 在编写与我们的库链接的自定义 Adob e 插件
  • 小/大 numpy 数组的释放处理方式是否不同?

    我正在尝试调试我的大型 Python 应用程序的内存问题 大部分记忆都在numpy由Python类管理的数组 所以Heapy http guppy pe sourceforge net 等等都是无用的 因为它们不占内存numpy数组 因此
  • 将值存储为变量或再次调用方法更好吗?

    最近 我开始学习一些Java 从我对 JVM 的了解来看 JIT 使其在需要 CPU 周期的操作 即调用方法 上变得非常快 但也使其对内存产生了饥饿感 因此 当我需要与以前相同的方法获得相同的输出时 将之前的输出存储在变量中并再次使用它 同
  • 如何测量Python中对象的内存使用情况?

    我有一个Python课程foo其中包含 数据 整数 浮点数 列表 整数 浮点数和其他对象的列表 字典 整数 浮点数 其他对象的 假设没有反向引用 循环 是否有一种简单的方法来测量一个进程的总内存使用量foo目的 本质上 我正在寻找一个递归版
  • CUDA 代码会损坏 GPU 吗?

    在测试包含内存错误的 CUDA 时 我的屏幕被冻结了 重新启动后我无法再检测到显卡 我的代码是否有可能物理损坏该卡 这发生在 Ubuntu 14 04 下 我不知道该卡的型号 因为我无法检测到它 但我记得它是一张相当新的卡 感谢所有的评论我
  • Bison/Flex 中哪里可以释放内存?

    我使用 Bison 和 Flex 的时间或多或少有 1 个月 所以如果我没有看到明显的东西 但我不认为是 我很抱歉 我在使用 Flex Bison 释放内存时遇到问题 我的代码如下所示 parser l DATE yylval str st
  • 为什么使用 boost::none 无法通过 nvcc 编译?

    我正在尝试编译以下代码 include
  • 了解流式多处理器 (SM) 和流式处理器 (SP)

    我正在尝试了解 GPU 的基本架构 我已经阅读了很多材料 包括这个非常好的答案 https stackoverflow com a 2213744 2386113 但我仍然很困惑 无法得到一个好的图片 我的理解 GPU 包含两个或多个流式多
  • 如何降级cuda版本

    我目前使用的是 cuda 版本 4 2 但我需要将其更改为 3 1 是否可以卸载当前版本 4 2 版 然后安装以前的版本 3 1 版 编辑 请参阅我的操作系统是linux ubuntu 10 04 64位 编辑 我找到了如何获取 3 1 版
  • python tracemalloc 模块分配统计信息何时会与 ps 或 pmap 中显示的内容不匹配?

    我正在尝试查找内存泄漏 所以我已经完成了 import tracemalloc tracemalloc start
  • 如何转储所有 NVCC 预处理器定义?

    我想达到同样的效果 gcc dM E lt dev null 如所描述的here https stackoverflow com q 2224334 1593077 但对于 nvcc 也就是说 我想转储所有 nvcc 的预处理器定义 唉 n
  • BASIC 中的 C 语言中的 PeekInt、PokeInt、Peek、Poke 等效项

    我想知道该命令的等效项是什么Peek and Poke 基本和其他变体 用 C 语言 类似PeekInt PokeInt 整数 涉及内存条的东西 我知道在 C 语言中有很多方法可以做到这一点 我正在尝试将基本程序移植到 C 语言 这只是使用

随机推荐