何时将 volatile 与寄存器/局部变量一起使用

2024-01-11

在 CUDA 中使用 volatile 限定符声明寄存器数组的含义是什么?

当我尝试使用 volatile 关键字和寄存器数组时,它删除了溢出寄存器内存到本地内存的数量。 (即强制 CUDA 使用寄存器而不是本地内存)这是预期的行为吗?

我在 CUDA 文档中没有找到有关寄存器数组的 volatile 用法的任何信息。

这是两个版本的 ptxas -v 输出

带有易失性限定符

    __volatile__ float array[32];

ptxas -v 输出

ptxas info    : Compiling entry function '_Z2swPcS_PfiiiiS0_' for 'sm_20'
ptxas info    : Function properties for _Z2swPcS_PfiiiiS0_
88 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads
ptxas info    : Used 47 registers, 16640 bytes smem, 80 bytes cmem[0], 8 bytes cmem[16]

没有 volatile 限定符

    float array[32];

ptxas -v 输出

ptxas info    : Compiling entry function '_Z2swPcS_PfiiiiS0_' for 'sm_20'
ptxas info    : Function properties for _Z2swPcS_PfiiiiS0_
96 bytes stack frame, 100 bytes spill stores, 108 bytes spill loads
ptxas info    : Used 51 registers, 16640 bytes smem, 80 bytes cmem[0], 8 bytes cmem[16]

The volatile限定符向编译器指定对变量的所有引用(读或写)都应产生内存引用,并且这些引用必须按照程序中指定的顺序。使用volatileShane Cook 的书《CUDA 编程》第 12 章对限定符进行了说明。

指某东西的用途volatile将避免编译器可以进行的一些优化,从而更改所使用的寄存器的数量。了解什么的最好方法volatile实际上做的就是拆解相关的__global__带或不带限定符的函数。

确实考虑以下核函数

__global__ void volatile_test() {

   volatile float a[3];

   for (int i=0; i<3; i++) a[i] = (float)i;
}

__global__ void no_volatile_test() {

   float a[3];

   for (int i=0; i<3; i++) a[i] = (float)i;
}

将上述核函数反汇编得到

code for sm_20
      Function : _Z16no_volatile_testv
.headerflags    @"EF_CUDA_SM20 EF_CUDA_PTX_SM(EF_CUDA_SM20)" 
/*0000*/        MOV R1, c[0x1][0x100]; /* 0x2800440400005de4 */
/*0008*/        EXIT ;                 /* 0x8000000000001de7 */


      Function : _Z13volatile_testv
.headerflags    @"EF_CUDA_SM20 EF_CUDA_PTX_SM(EF_CUDA_SM20)"
/*0000*/        MOV R1, c[0x1][0x100]; /* 0x2800440400005de4 */   
/*0008*/        ISUB R1, R1, 0x10;     /* 0x4800c00040105d03 */   R1 = address of a[0]
/*0010*/        MOV32I R2, 0x3f800000; /* 0x18fe000000009de2 */   R2 = 1
/*0018*/        MOV32I R0, 0x40000000; /* 0x1900000000001de2 */   R0 = 2
/*0020*/        STL [R1], RZ;          /* 0xc8000000001fdc85 */
/*0028*/        STL [R1+0x4], R2;      /* 0xc800000010109c85 */   a[0] = 0;
/*0030*/        STL [R1+0x8], R0;      /* 0xc800000020101c85 */   a[1] = R2 = 1;
/*0038*/        EXIT ;                 /* 0x8000000000001de7 */   a[2] = R0 = 2;

正如你所看到的,当不使用volatile关键字,编译器意识到a已设置但从未使用(实际上,编译器返回以下警告:变量“a”已设置但从未使用)并且几乎没有反汇编代码。

与此相反,当使用volatile关键字,所有引用a被转换为内存引用(在本例中为 write)。

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

何时将 volatile 与寄存器/局部变量一起使用 的相关文章

  • 为什么 gcc 和 NVCC (g++) 会看到两种不同的结构大小?

    我正在尝试将 CUDA 添加到 90 年代末编写的现有单线程 C 程序中 为此 我需要混合两种语言 C 和 C nvcc 是 c 编译器 问题在于 C 编译器将结构视为特定大小 而 C 编译器将相同的结构视为略有不同的大小 那很糟 我对此感
  • 如何在C++中的cudaDeviceReset()之后重用tensorflow?

    我正在使用 C 开发一个大型 CUDA 应用程序 该应用程序运行各种模型 需要完全释放所有 GPU 内存 否则其他操作将失败 我能够在关闭所有 tf 会话并运行 cudaDeviceReset 后释放所有内存 但之后我无法运行任何新的张量流
  • CUDA程序导致nvidia驱动程序崩溃

    当我超过大约 500 次试验和 256 个完整块时 我的 monte carlo pi 计算 CUDA 程序导致我的 nvidia 驱动程序崩溃 这似乎发生在 monteCarlo 内核函数中 任何帮助都会受到赞赏 include
  • 有没有办法使用 GPU 调整图像大小?

    有没有办法使用可通过 NET 应用程序使用的 GPU 图形卡 调整图像大小 我正在寻找一种极其高效的方法来调整图像大小 并且听说 GPU 可以比 CPU 更快地完成此操作 使用 C 的 GDI 是否有已知的实现或示例代码使用 GPU 来调整
  • CUDA 中的广义霍夫变换 - 如何加快分箱过程?

    正如标题所示 我正在对并行计算机视觉技术进行一些个人研究 使用 CUDA 我尝试实现 GPGPU 版本的霍夫变换 我遇到的唯一问题是在投票过程中 我调用atomicAdd 来防止多个同时写入操作 但我似乎没有获得太多的性能效率 我在网上搜索
  • 多个进程可以共享一个 CUDA 上下文吗?

    这个问题是 Jason R 的后续问题comment https stackoverflow com questions 29964392 multiple cuda contexts for one device any sense co
  • 在linux上编译一个基本的OpenCV + Cuda程序

    我过去在linux上使用过opencv 但没有使用过cuda 几个月来我一直在与以下编译错误作斗争 在尝试了许多解决方案后 我放弃并使用 Windows 不过 我真的很想在 Linux 上工作 这是我用来编译 opencv gpu 网站上给
  • 是否可以在GPU中实现Huffman解码?

    我们有一个用霍夫曼编码编码的数据库 这里的目的是将其及其关联的解码器复制到 GPU 上 然后在 GPU 上对数据库进行解码 并在解码后的数据库上执行操作 而无需将其复制回 CPU 上 我还远远不是霍夫曼专家 但我所知道的少数人表明 它似乎是
  • 如何并行从数组中删除零值

    如何使用 CUDA 并行有效地从数组中删除零值 有关零值数量的信息是预先可用的 这应该可以简化这项任务 重要的是数字必须保持源数组中的顺序 当被复制到结果数组时 Example 该数组将例如包含以下值 0 0 19 7 0 3 5 0 0
  • 涉及优化器的局部变量构造和销毁

    如果我有这个代码 class A class B void dummy A a B b 我知道变量a and b将以相反的分配顺序销毁 b将首先被摧毁 然后a 但我可以确定优化器永远不会交换的分配和构造a and b 或者我必须使用vola
  • CUDA 估计 2D 网格数据的每块线程数和块数

    首先我要说的是 我已经仔细阅读了所有类似的问题 确定每个块的线程和每个网格的块 https stackoverflow com questions 4391162 cuda determining threads per block blo
  • Nvcc 的版本与 CUDA 不同

    我安装了 cuda 7 但是当我点击 nvcc version 时 它打印出 6 5 我想在 GTX 960 卡上安装 Theano 库 但它需要 nvcc 7 0 我尝试重新安装cuda 但它没有更新nvcc 当我运行 apt get i
  • DirectX 世界视图矩阵乘法 - GPU 或 CPU 的地方

    我是 directx 的新手 但令我惊讶的是 我看到的大多数示例中 世界矩阵和视图矩阵都是作为顶点着色器的一部分相乘 而不是与 CPU 相乘并将结果传递给着色器 对于刚性对象 这意味着您为对象的每个顶点将相同的两个矩阵相乘一次 我知道 GP
  • 如何在 CUDA 中执行多个矩阵乘法?

    我有一个方阵数组int M 10 以便M i 定位第一个元素i th 矩阵 我想将所有矩阵相乘M i 通过另一个矩阵N 这样我就收到了方阵数组int P 10 作为输出 我看到有不同的可能性 分配不同元素的计算M i 到不同的线程 例如 我
  • iOS 上的 OpenCV - GPU 使用情况?

    我正在尝试开发一个 iOS 应用程序 可以对来自相机的视频执行实时效果 就像 iPad 上的 Photobooth 一样 我熟悉 OpenCV 的 API 但如果大多数处理是在 CPU 上完成而不是在 GPU 上完成 我担心 iOS 上的性
  • 使用 CUDA 进行逐元素向量乘法

    我已经在 CUDA 中构建了一个基本内核来执行逐元素两个复向量的向量 向量乘法 内核代码插入如下 multiplyElementwise 它工作正常 但由于我注意到其他看似简单的操作 如缩放向量 在 CUBLAS 或 CULA 等库中进行了
  • TensorRT 多线程

    我正在尝试使用 python API 来使用 TensorRt 我试图在多个线程中使用它 其中 Cuda 上下文与所有线程一起使用 在单个线程中一切正常 我使用 docker 和 tensorrt 20 06 py3 图像 onnx 模型和
  • cuda中内核的并行执行

    可以说我有三个全局数组 它们已使用 cudaMemcpy 复制到 GPU 中 但 c 中的这些全局数组尚未使用 cudaHostAlloc 分配 以便分配页面锁定的内存 而不是简单的全局分配 int a 100 b 100 c 100 cu
  • NV_path_rendering替代方案[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我刚刚观看了 Siggraph 2012 的一个非常令人印象深刻的演示 http nvidia fullviewmedia com sig
  • 如何使用 CUDA/Thrust 对两个数组/向量根据其中一个数组中的值进行排序

    这是一个关于编程的概念问题 总而言之 我有两个数组 向量 我需要对一个数组 向量进行排序 并将更改传播到另一个数组 向量中 这样 如果我对 arrayOne 进行排序 则对于排序中的每个交换 arrayTwo 也会发生同样的情况 现在 我知

随机推荐