如何在 CUDA 中进行原子加载

2023-12-20

我的问题是如何在 CUDA 中进行原子加载。原子交换可以模拟原子存储。原子加载是否可以以类似的方式廉价地模拟? 我可以使用带有 0 的原子添加来自动加载内容,但我认为它很昂贵,因为它执行原子读取-修改-写入而不是仅读取。


除了使用volatile正如其他答案中建议的那样,使用__threadfence还需要适当地获得具有安全内存排序的原子加载。

虽然一些评论说只使用普通读取,因为它不能撕裂,但这与原子加载不同。原子不仅仅是撕裂:

正常读取可能会重用寄存器中已有的先前加载,因此可能不会反映其他 SM 具有所需内存排序的更改。例如,int *flag = ...; while (*flag) { ... }只能阅读flag一次并在循环的每次迭代中重用该值。如果您正在等待另一个线程更改标志的值,您将永远不会观察到更改。这volatile修饰符确保每次访问时实际上都是从内存中读取该值。请参阅关于易失性的 CUDA 文档 https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#volatile-qualifier了解更多信息。

此外,您需要使用内存栅栏来在调用线程中强制执行正确的内存排序。如果没有栅栏,您将获得 C++11 术语中的“宽松”语义,而在使用原子进行通信时这可能是不安全的。

例如,假设您的代码(非原子地)将一些大数据写入内存,然后使用正常写入来设置原子标志以指示数据已被写入。指令可能会被重新排序,硬件缓存行可能不会在设置标志之前被刷新等等。结果是这些操作不能保证以任何顺序执行,并且其他线程可能不会按照您期望的顺序观察这些事件:允许写入标志before受保护的数据被写入。

同时,如果读取线程在有条件加载数据之前也使用正常读取来检查标志,则会在硬件级别出现竞争。无序和/或推测执行可能会在标志读取​​完成之前加载数据。然后使用推测加载的数据,该数据可能无效,因为它是在读取标志之前加载的。

放置得当的内存栅栏可以通过强制执行指令重新排序来防止此类问题,从而不会影响您所需的内存顺序,并且以前的写入对其他线程可见。__threadfence()和朋友也被覆盖在 CUDA 文档中 https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#memory-fence-functions.

将所有这些放在一起,在 CUDA 中编写您自己的原子加载方法看起来像:

// addr must be aligned properly.
__device__ unsigned int atomicLoad(const unsigned int *addr)
{
  const volatile unsigned int *vaddr = addr; // volatile to bypass cache
  __threadfence(); // for seq_cst loads. Remove for acquire semantics.
  const unsigned int value = *vaddr;
  // fence to ensure that dependent reads are correctly ordered
  __threadfence(); 
  return value; 
}

// addr must be aligned properly.
__device__ void atomicStore(unsigned int *addr, unsigned int value)
{
  volatile unsigned int *vaddr = addr; // volatile to bypass cache
  // fence to ensure that previous non-atomic stores are visible to other threads
  __threadfence(); 
  *vaddr = value;
}

对于其他非撕裂加载/存储大小,这可以类似地编写。

通过与一些从事 CUDA 原子工作的 NVIDIA 开发人员交谈,我们似乎应该开始看到 CUDA 中对原子的更好支持,并且 PTX 已经包含具有获取/释放内存顺序的加载/存储指令 https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#release-acquire-patterns语义——但目前无法在不诉诸内联 PTX 的情况下访问它们。他们希望在今年的某个时候将它们添加进来。一旦这些就位,一个完整的std::atomic实施应该不会落后太远。

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

如何在 CUDA 中进行原子加载 的相关文章

  • 在 Windows 上的 Qt Creator 中编译 Cuda 代码

    几天来我一直在尝试获取在 32 位 Windows 7 系统上运行的 Qt 项目文件 我希望 需要在其中包含 Cuda 代码 这种组合要么非常简单 以至于没有人愿意在网上放一个例子 要么非常困难 似乎没有人成功 不管怎样 我发现的唯一有用的
  • 如何在 Linux 中分析 PyCuda 代码?

    我有一个简单的 经过测试的 pycuda 应用程序 正在尝试对其进行分析 我尝试过 NVidia 的 Compute Visual Profiler 它运行该程序 11 次 然后发出以下错误 NV Warning Ignoring the
  • CUDA错误:在python中使用并行时初始化错误

    我的代码使用 CUDA 但运行速度仍然很慢 因此 我将其更改为使用 python 中的多处理 pool map 并行运行 但我有CUDA ERROR initialization error 这是函数 def step M self ite
  • cuda中的count3非常慢

    我在 CUDA 中编写了一个小程序 用于计算 C 数组中有多少个 3 并打印它们 include
  • 如何在 CUDA 应用程序中构建数据以获得最佳速度

    我正在尝试编写一个简单的粒子系统 利用 CUDA 来更新粒子位置 现在 我定义的粒子有一个对象 该对象的位置由三个浮点值定义 速度也由三个浮点值定义 更新粒子时 我向速度的 Y 分量添加一个常量值以模拟重力 然后将速度添加到当前位置以得出新
  • CUDA:如何检查计算能力是否正确?

    使用较高计算能力编译的 CUDA 代码将在计算能力较低的设备上完美执行很长一段时间 然后有一天在某些内核中默默地失败 我花了半天时间追寻一个难以捉摸的错误 结果发现构建规则已经sm 21而该设备 Tesla C2050 是2 0 是否有任何
  • 在新线程中调用支持 CUDA 的库

    我编写了一些代码并将其放入它自己的库中 该库使用 CUDA 在 GPU 上进行一些处理 我正在使用 Qt 构建 GUI 前端 作为加载 GUI 的一部分 我调用 CUresult res CUdevice dev CUcontext ctx
  • 用于类型比较的 Boost 静态断言

    以下问题给我编译器错误 我不知道如何正确编写它 struct FalseType enum value false struct TrueType enum value true template
  • libstdc++.so.6 与 cuda 相关的链接器问题

    今天我在链接我编译的 cuda 内容时遇到了问题 我有一个最新的 debian 测试 w 2 6 32 3 amd64 我整天都在写我的代码 不时编译 没有问题 但在进行了较小的代码更改后 我收到以下错误 gcc o pa CUDA o h
  • Cuda Bayer/CFA 去马赛克示例

    我编写了一个 CUDA4 Bayer 去马赛克例程 但它比在 16 核 GTS250 上运行的单线程 CPU 代码慢 块大小是 16 16 图像暗淡是 16 的倍数 但更改此值并不会改善它 我做了什么明显愚蠢的事情吗 calling rou
  • cudaMallocManaged() 返回“不支持的操作”

    在 CUDA 6 0 中尝试托管内存给了我operation not supported打电话时cudaMallocManaged include cuda runtime h include
  • 使用 QuasirandomGenerator (对于傻瓜来说)

    我是 CUDA 的新手 我正在努力在内核中生成随机数 我知道有不同的实现 而且 在 SDK 4 1 中有一个 Niederreiter 拟随机序列生成器的示例 我不知道从哪里开始 我有点悲伤 感觉自己像个傻瓜 有人可以制作一个使用 Nied
  • “计算能力”是什么意思? CUDA?

    我是CUDA编程新手 对此了解不多 您能告诉我 CUDA 计算能力 是什么意思吗 当我在大学服务器上使用以下代码时 它向我显示了以下结果 for device 0 device lt deviceCount device cudaDevic
  • 多个进程可以共享一个 CUDA 上下文吗?

    这个问题是 Jason R 的后续问题comment https stackoverflow com questions 29964392 multiple cuda contexts for one device any sense co
  • 为什么numba cuda调用几次后运行速度变慢?

    我正在尝试如何在 numba 中使用 cuda 然而我却遇到了与我预想不同的事情 这是我的代码 from numba import cuda cuda jit def matmul A B C Perform square matrix m
  • CUDA 常量内存是否应该被均匀地访问?

    我的 CUDA 应用程序的恒定内存小于 8KB 既然它都会被缓存 我是否需要担心每个线程访问相同的地址以进行优化 如果是 如何确保所有线程同时访问同一地址 既然它都会被缓存 我是否需要担心每个线程访问相同的地址以进行优化 是的 这缓存本身每
  • 加速Cuda程序

    要更改哪一部分来加速此代码 代码到底在做什么 global void mat Matrix a Matrix b int tempData new int 2 tempData 0 threadIdx x tempData 1 blockI
  • cuda中有模板化的数学函数吗? [复制]

    这个问题在这里已经有答案了 我一直在寻找 cuda 中的模板化数学函数 但似乎找不到 在普通的 C 中 如果我调用std sqrt它是模板化的 并且将根据参数是浮点数还是双精度数执行不同的版本 我想要这样的 CUDA 设备代码 我的内核将真
  • 在 cudaFree() 之前需要 cudaDeviceSynchronize() 吗?

    CUDA 版本 10 1 帕斯卡 GPU 所有命令都发送到默认流 void ptr cudaMalloc ptr launch kernel lt lt lt gt gt gt ptr cudaDeviceSynchronize Is th
  • cuda中内核的并行执行

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

随机推荐

  • RecyclerView.Adapter 内的 onActivityResult 未使用

    我在适配器内有一个按钮 可以进入画廊 MyAdapter extends RecyclerView Adapter
  • 自定义数据类型在设备之间不同步

    我正在尝试使用 Google Fit API 来存储自定义数据类型 我可以在单个设备上很好地插入和检索它们 但是当我在不同设备上登录同一个 Google 帐户时 数据不存在 我可以从每个设备创建和检索数据 但它们都保留自己的数据 并且不通过
  • 更改 matplotlib pyplot 图例中线条的线宽[重复]

    这个问题在这里已经有答案了 我想更改 pyplot 图例中的线条样本的厚度 宽度 图例中的线样本的线宽与它们在图中表示的线相同 因此 如果线y1 has linewidth 7 0 图例对应的y1标签上也会有linewidth 7 0 我希
  • 启动没有控制台窗口的程序(在后台)

    我想在 Windows 启动时启动一个简单的程序 但我不想显示与该程序关联的控制台输出窗口 只是为了测试 该程序可以简单如下 int main int argc char argv while 1 printf hello world n
  • 为什么 PHP 中 65.6*100%10 等于 9 而不是 0?

    echo 65 7 100 10 0 echo 65 6 100 10 9 lt echo 6560 10 0 echo 65 5 100 10 0 有人可以解释一下为什么吗 EDIT 对于人类或非程序员来说 结果 9 显然是错误的 我怎样
  • 在 Outlook html 电子邮件中,浮动不起作用

    我想要这样的布局 其中有一个矩形框 左边的盒子里有一个文本 右边有一个图像 这在浏览器中看起来很好 但是当作为 html 电子邮件发送时 在 Outlook 中浮动权限似乎不起作用 它将图像放在文本下方的下一行 关于如何实现这项工作有什么想
  • html 表格如何通过更改悬停时的边框来突出显示列?

    我正在探索如何设计表格样式 以便当鼠标悬停在列上时可以更改边框 当鼠标悬停在一列上时 我想通过更改边框颜色来突出显示该列 需要强调的是 我将以下 JavaScript 代码与 jQuery 库结合使用 td hover function v
  • 构造函数:默认参数和委托参数之间的区别

    今天 我偶然发现这些标准声明 http en cppreference com w cpp container vector vector of std vector构造函数 until C 14 explicit vector const
  • 如何使用 pip 将 vcs 中的 Python 包可编辑安装到特定目录中?

    默认情况下 pip 安装editable打包成srcPython安装目录的子目录 我想使用 pip 支持从源代码控制中检出软件包 将版本控制中的软件包安装到我选择的目录中 例如 pip install e git https github
  • HATEOAS 中“_embedded”的含义和用法

    我正在使用 Spring Data REST 它支持 HATEOAS 我对这个范式很陌生 In GET来自我的 RESTful Web 服务的响应 我经常在名为的节点内收到结果 embedded 我在想 what is embedded节点
  • JPanel 在 JFrame 上没有改变

    我的想法是拥有一个 全局 JFrame 然后我可以根据需要添加 删除 JPanel 以创建一个流畅的应用程序 目前 当我尝试从第一个 JPanel 更改为第二个 JPanel 时 第二个 JPanel 将不会显示 我的代码如下 处理程序 运
  • 计算每个段落中的字符数

    我正在尝试找到一种方法来计算页面上每个段落中的字符数 我发现下面这个小片段可以计算每个段落中的单词数 效果很好 是否可以修改为也包括字符数 互联网上有很多解决方案 但它们只关注特定的字符串或文本区域 并且往往变得非常长和复杂 我不介意计数中
  • 使用默认值从 Mac 上的命令行修改 Plist

    有谁知道如何使用命令行修改 Plist 文件defaults 目前有两个词典URL types大批 我需要添加另一个 我尝试过的每个命令要么替换了整个字典 要么创建了一个名为的新数组URL types而不是编辑它 关于如何在默认情况下完成此
  • 如何检测数据集中的所有空列并删除\删除它们?

    正如标题中所建议的 我想删除所有空列 变量 其中所有记录均为空或等于 null 或 以减少以后执行的时间成本 详细场景 我有一个包含 1000 列的 dataset 其中一些 很多是空的 现在我想创建一个新的数据集 其中需要在先前数据集的某
  • 如何存储由 std::unique_ptr 给出的抽象类的对象向量?

    我有一个循环 其中我使用一个函数将 std unique ptr 返回到抽象类的对象 我想通过push back将这些对象存储到std vector中 但由于对象是抽象类型 我收到以下错误 error cannot allocate an
  • 防止 Perl 中的循环引用内存泄漏

    我最近问了一个question https stackoverflow com questions 31971633 perl memory management when overwriting objects关于 Perl 中的覆盖对象
  • 如何在asp.net core中将ViewDataDictionary与Html.Partial一起使用?

    我的案例是这样的 Model public class Book public string Id get set public string Name get set public class Comment public string
  • 如何通过spark REST API获取所有作业状态?

    我正在使用 Spark 1 5 1 我想通过 REST API 检索所有作业状态 我使用得到正确的结果 api v1 applications appId 但在找工作的同时 api v1 applications appId jobs得到
  • 金字塔和变色龙中的ajax小部件

    我希望能够在服务器端轻松创建由变色龙和金字塔支持的ajax 小部件 Pyramid 是否提供任何可以使编写小部件变得容易的管道代码 我当前的方法是我有一个使用 home pt 作为渲染器的主视图 home pt 使用宏 base pt 定义
  • 如何在 CUDA 中进行原子加载

    我的问题是如何在 CUDA 中进行原子加载 原子交换可以模拟原子存储 原子加载是否可以以类似的方式廉价地模拟 我可以使用带有 0 的原子添加来自动加载内容 但我认为它很昂贵 因为它执行原子读取 修改 写入而不是仅读取 除了使用volatil