cuda:扭曲发散开销与额外算术

2024-02-03

当然,扭曲发散,通过if and switch语句,在 GPU 上要不惜一切代价避免。

但是扭曲发散的开销是多少(仅调度some执行某些行的线程)与额外无用的算术?

考虑以下虚拟示例:

版本1:

__device__ int get_D (int A, int B, int C)
{
    //The value A is potentially different for every thread.

    int D = 0;

    if (A < 10)
        D = A*6;
    else if (A < 17)
        D = A*6 + B*2;
    else if (A < 26)
        D = A*6 + B*2 + C; 
    else 
        D = A*6 + B*2 + C*3;

    return D;
}

vs.

版本2:

__device__ int get_D (int A, int B, int C)
{
    //The value A is potentially different for every thread.

    return  A*6 + (A >= 10)*(B*2) + (A < 26)*C + (A >= 26)*(C*3);
}

我的真实场景更复杂(更多条件),但想法相同。

问题:

扭曲发散的开销(在调度中)是否如此之大以至于版本 1)比版本 2 慢?

版本 2 需要比版本 1 更多的 ALU,其中大部分都浪费在“乘以 0”上(只有少数条件计算结果为 1 而不是 0)。这是否会将有价值的 ALU 占用在无用的操作中,从而延迟其他扭曲中的指令?


通常很难提供此类问题的具体答案。影响2个案例对比分析的因素有很多:

  • 你说 A 对于每个线程来说可能是不同的,但这种情况的真实程度实际上会影响比较。
  • 总的来说,您的代码是否受计算限制或带宽限制肯定会影响答案。 (如果您的代码受带宽限制,则可能有no两种情况之间的性能差异)。
  • 我知道你已经将 A、B、C 识别为整数,但看似无害的更改,例如使它们float可能会显着影响答案。

幸运的是,有一些分析工具可以帮助给出清晰、具体的答案(或者可能表明这两种情况之间没有太大区别)。您已经很好地识别了您关心的 2 个具体案例。为什么不对2进行基准测试?如果您想更深入地挖掘,分析工具可以提供有关指令重放(由于扭曲发散而产生)带宽/计算限制指标等的统计数据。

我不得不对这个笼统的声明表示异议:

当然,在 GPU 上要不惜一切代价避免通过 if 和 switch 语句发生扭曲发散。

这根本不是真的。机器处理发散控制流的能力实际上是feature这使我们能够使用更友好的语言(例如 C/C++)对其进行编程,并且实际上将其与其他一些不为程序员提供这种灵活性的加速技术区分开来。

与任何其他优化工作一样,您应该首先将注意力集中在繁重的工作上。您提供的这段代码是否构成了您的应用程序完成的大部分工作?在大多数情况下,将这种级别的分析工作投入到基本上是粘合代码或不属于应用程序主要工作的部分中是没有意义的。

如果这是您代码的大部分工作,那么分析工具确实是一种获得有意义的良好答案的强大方法,这些答案可能比尝试进行学术分析更有用。

现在我来回答你的问题:

扭曲发散的开销(在调度中)是否如此之大以至于版本 1)比版本 2 慢?

这将取决于实际发生的分支的具体水平。在最坏的情况下,如果有 32 个线程的完全独立的路径,机器将完全序列化,并且您实际上以峰值性能的 1/32 运行。线程的二元决策树类型细分不能产生这种最坏的情况,但肯定可以通过树的末尾来接近它。由于最后的线程完全发散,可能会观察到此代码的速度下降超过 50%,甚至可能下降 80% 或更高。但这在统计上取决于差异实际发生的频率(即它依赖于数据)。在最坏的情况下,我预计版本 2 会更快。

版本 2 需要比版本 1 更多的 ALU,其中大部分都浪费在“乘以 0”上(只有少数条件计算结果为 1 而不是 0)。这是否会将有价值的 ALU 占用在无用的操作中,从而延迟其他扭曲中的指令?

float vs. int可能实际上对这里有帮助,并且可能是您可以考虑探索的东西。但第二种情况(对我来说)似乎与第一种情况具有相同的比较,但有一些额外的乘法。在浮点情况下,机器每个时钟每个线程可以执行一次乘法,因此速度相当快。在 int 情况下,速度较慢,您可以根据架构查看具体的指令吞吐量here http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#arithmetic-instructions。我不会过度担心那种算术水平。再说一次,它可能会让完全没有区别如果您的应用程序受内存带宽限制。

另一种梳理所有这些的方法是编写内核来比较感兴趣的代码,编译为 ptx (nvcc -ptx ...) 并比较 ptx 指令。这可以更好地了解机器线程代码在每种情况下的样子,如果您只是执行指令计数之类的操作,您可能会发现两种情况之间没有太大区别(在这种情况下应该有利于选项 2) 。

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

cuda:扭曲发散开销与额外算术 的相关文章

  • CUDA 中的广义霍夫变换 - 如何加快分箱过程?

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

    我正在尝试并行缩减以对 CUDA 中的数组求和 目前我传递一个数组来存储每个块中元素的总和 这是我的代码 include
  • 传递给 CUDA 的结构中的指针

    我已经搞砸了一段时间了 但似乎无法正确处理 我正在尝试将包含数组的对象复制到 CUDA 设备内存中 然后再复制回来 但当我遇到它时我会跨过那座桥 struct MyData float data int dataLen void copyT
  • 使 CUDA 内存不足

    我正在尝试训练网络 但我明白了 我将批量大小设置为 300 并收到此错误 但即使我将其减少到 100 我仍然收到此错误 更令人沮丧的是 在 1200 个图像上运行 10 epoch 大约需要 40 分钟 有什么建议吗 错了 我怎样才能加快这
  • 如何确定完整的 CUDA 版本 + 颠覆版本?

    Linux 上的 CUDA 发行版曾经有一个名为version txt例如 CUDA Version 10 2 89 这非常有用 但是 从 CUDA 11 1 开始 该文件不再存在 我如何在 Linux 上通过命令行确定并检查 path t
  • 如何并行从数组中删除零值

    如何使用 CUDA 并行有效地从数组中删除零值 有关零值数量的信息是预先可用的 这应该可以简化这项任务 重要的是数字必须保持源数组中的顺序 当被复制到结果数组时 Example 该数组将例如包含以下值 0 0 19 7 0 3 5 0 0
  • 运行时 API 应用程序中的 cuda 上下文创建和资源关联

    我想了解如何在 cuda 运行时 API 应用程序中创建 cuda 上下文并与内核关联 我知道这是由驱动程序 API 在幕后完成的 但我想了解一下创作的时间线 首先 我知道 cudaRegisterFatBinary 是第一个 cuda a
  • CUDA线程执行顺序

    我有一个 CUDA 程序的以下代码 include
  • C# - 获取 GPU 的总使用百分比

    我正在向我的程序添加一些新功能 这些功能当前通过串行连接将 CPU 使用情况和 RAM 使用情况发送到 Arduino 请参阅this https create arduino cc projecthub thesahilsaluja cp
  • Yocto for Nvidia Jetson 由于 GCC 7 而失败 - 无法计算目标文件的后缀

    我正在尝试将 Yocto 与 meta tegra 一起使用 https github com madisongh meta tegra https github com madisongh meta tegra 为 Nvidia Jets
  • CUDA 矩阵加法时序,按行与按行比较按栏目

    我目前正在学习 CUDA 并正在做一些练习 其中之一是实现以 3 种不同方式添加矩阵的内核 每个元素 1 个线程 每行 1 个线程和每列 1 个线程 矩阵是方阵 并被实现为一维向量 我只需用以下命令对其进行索引 A N row col 直觉
  • CUDA、NPP 滤波器

    CUDA NPP 库支持使用 nppiFilter 8u C1R 命令过滤图像 但不断出现错误 我可以毫无问题地启动并运行 boxFilterNPP 示例代码 eStatusNPP nppiFilterBox 8u C1R oDeviceS
  • 如何使用 CUDA/Thrust 对两个数组/向量根据其中一个数组中的值进行排序

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

    我正在 VS 2012 中运行以下程序来尝试 Thrust 函数查找 include cuda runtime h include device launch parameters h include
  • 内联 PTX 汇编代码强大吗?

    我看到一些代码示例 人们在 C 代码中使用内联 PTX 汇编代码 CUDA工具包中的文档提到PTX很强大 为什么会这样呢 如果我们在 C 代码中使用这样的代码 我们会得到什么好处 内联 PTX 使您可以访问未通过 CUDA 内在函数公开的指
  • 通过 cuFFT 进行逆 FFT 缩放

    每当我使用 cuFFT 绘制程序获得的值并将结果与 Matlab 的结果进行比较时 我都会得到相同形状的图形 并且最大值和最小值位于相同的点 然而 cuFFT 得到的值比 Matlab 得到的值大得多 Matlab代码是 fs 1000 s
  • OpenCL 内核在 Nvidia GPU 上每个线程使用多少寄存器?

    我的第一个问题是如何获取 Nvidia GPU 上 OpenCL 内核代码的寄存器使用信息 因为 nvcc 编译器给出了相同的使用信息nvcc ptxas options vCUDA 内核代码的标志 我还从 AMD GPU for Open
  • CUDA 中指令重放的其他原因

    这是我从 nvprof CUDA 5 5 获得的输出 Invocations Metric Name Metric Description Min Max Avg Device Tesla K40c 0 Kernel MyKernel do
  • cuda 文件组织的有效方式:.cpp .h .cu .cuh .curnel 文件

    cuda最容易理解 最高效的代码组织是什么 经过一番调查后 我发现 cuda 函数声明应位于 cuh 文件中 实现位于 cu 文件中 内核函数实现位于 curnel 文件中 其他 C 内容通常在 cpp 和 h 文件中 最近我发布了一个问题
  • 有条件减少 CUDA

    我需要总结一下100000值存储在数组中 但带有条件 有没有办法在 CUDA 中做到这一点以快速产生结果 任何人都可以发布一个小代码来做到这一点吗 我认为 要执行条件约简 您可以直接将条件引入为乘法0 假 或1 真 加数 换句话说 假设您希

随机推荐

  • 虚拟成员函数的目的是什么?

    C 中函数重写和虚函数之间有什么区别 虚拟成员函数可以在派生类中重写 在派生类中重新定义函数称为函数重写 为什么我们实际上有虚函数 虚函数 方法只是一个函数 通过重新定义函数的工作方式 使用相同的签名 可以在子类 或 C 术语中的派生类 中
  • 动态创建的元素失去间距

    我有一个带有两个 span 元素的 div a div span My workspace span span class glyphicon glyphicon pencil style color white span div 否则 我
  • C99 fesetround()/fegetround() 状态是每个线程还是每个进程?

    我在网上找到的 C 和 POSIX 参考资料没有指定 C99 的 fesetround 的线程安全性 甚至 GNU 文档也没有 1 状态是每个线程还是每个进程 1 https www gnu org software hello manua
  • 多个服务器上的单个 SSL 证书可将推送通知发送到同一应用程序

    是否可以在多个服务器上使用单个 SSL 证书向同一应用程序发送推送通知 我们有客户端和服务器 客户端将从应用程序商店下载 服务器将由个人客户在自己的网络上安装 对于所有客户 客户端应用程序都是相同的 我们无法为每个客户提交单独的应用程序 那
  • 使用 MEF 导入 WPF DataTemplate?

    我一直将 MEF 视为一种可扩展性框架 除了一点之外 我几乎被说服了 假设我想导入 ViewModel 和 View 来显示它 我认为 正确 的方法是让 MEF 部分导出 ViewModel 类和显示 ViewModel 的 DataTem
  • Python 社交身份验证 Django 模板示例

    有人有一个使用的开放示例吗Python 社交认证 http python social auth readthedocs org 在模板中使用 Django 我查看了他们的 Github 存储库 在 django exmaple 中 没有任
  • distutils 可以在不安装的情况下执行依赖性检查吗?

    是否可以让 distutils 只运行 python 模块依赖性分析 并且可能安装缺少的模块 而不实际安装有问题的 python 模块 我想象一个命令如下 setup py check dependencies 这将报告目标系统上是否缺少任
  • Bootstrap 4 在选择字段上验证时出现问题

    我是 jQuery 和 Bootstrap 的新手 我使用 jquery 和 Bootstrap 4 来验证我的表单模式 每当出现错误时 它必须在相应字段下方显示错误 但在我的情况下 选择字段会被错误和选择字段消失 但对于输入字段来说效果很
  • CSS 中的“>”是什么意思? [复制]

    这个问题在这里已经有答案了 可能的重复 CSS 规则中的 gt 是什么意思 https stackoverflow com questions 3225891 what does mean in css rules 什么是 gt CSS中的
  • 显示 Woocommerce 产品的默认变化价格

    我需要在 Woocommerce 产品中显示默认变化价格 我发现这篇文章和代码有效 gt Woocommerce 显示默认变化价格 https stackoverflow com questions 32319835 woocommerce
  • 在 Linux 上创建带范围的 wxSlider

    我正在尝试使用 Python 中的 wxSlider 创建一个带有范围选择选项的滑块 它有一个可选的范围参数 但问题是 SL SELRANGE 允许用户在滑块上选择范围 仅限 Windows 我正在使用Linux 我想我可以继承 wxSli
  • 在 UITableView 中点击单元格时显示 UIMenuController 时出现问题

    当用户长按分组 UITableView 中的单元格时 我尝试显示自定义 UIMenuController 但是 在成功检测到长按后 我似乎无法显示 UIMenuController 任何帮助是极大的赞赏 MyViewController h
  • 第一个 Mac 应用程序 - Push viewcontroller

    我有一个问题 我做了一些 iphone 应用程序 现在我想做一些 mac 应用程序 从一个干净的应用程序中 我在 MainMenu xib 上添加一个按钮 然后使用一个操作将 NSViewController 添加到 MainMenu 来自
  • 如何在 C++ 中反转字符串向量? [复制]

    这个问题在这里已经有答案了 我有一个字符串向量 我想反转该向量并打印它 或者简单地说 以相反的顺序打印该向量 我该怎么做呢 如果你想以相反的顺序打印向量 include
  • 将 Cakephp 项目从 Cakephp 2.6.2 升级到 3.8 的最佳方法

    我的任务是将遗留系统从 Cakephp2 6 2 升级到 Cakephp3 8 显然 这两个是截然不同的 但是有没有一种简单的方法可以让旧项目与新蛋糕版本一起工作 或者有人可以引导我走向正确的方向 找到最好的方法来做到这一点 不存在适合所有
  • 如何使用@Index JPA注释在主键上设置索引名称?

    我的工具 gt Java 8 JPA 2 1 和 Hibernate 4 我只使用 JPA2 1 注释 码头中的代码 gt Entity Table indexes Index name INDEX PK columnList ID pub
  • 如何正确“关闭”node.js 服务器?

    根据文档 http nodejs org api net html net server close callback呼叫server close 停止服务器接受新连接并保留现有连接 所以我的代码是 var http require htt
  • 如何在 ASP .NET CORE Identity 中通过 SignInManager 登录后获取用户声明?

    I have an ASP NET Core 2 0 project in which I am using Microsoft s Identity framework for authentication authorization I
  • 对多个 git 项目使用单个 git 存储库

    我很便宜 我不想为很多 github 帐户付费 我有一个看起来像这样的项目结构 repo是项目根 repo 项目1是我有一个Java项目的地方 repo herokurails1是我有一个 Ruby Rails 项目的地方 该项目部署到 h
  • cuda:扭曲发散开销与额外算术

    当然 扭曲发散 通过if and switch语句 在 GPU 上要不惜一切代价避免 但是扭曲发散的开销是多少 仅调度some执行某些行的线程 与额外无用的算术 考虑以下虚拟示例 版本1 device int get D int A int