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:扭曲发散开销与额外算术 的相关文章

  • Tensorflow:Cuda 计算能力 3.0。所需的最低 Cuda 能力为 3.5

    我正在从源安装tensorflow 文档 https www tensorflow org versions r0 10 get started os setup html installing from sources Cuda驱动版本
  • 有条件减少 CUDA

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

    我正在尝试使用 OpenGL 和 CUDA 制作一个简单的用于云和烟雾模拟的粒子系统 如何使粒子系统中的粒子表现得像真正的云或烟雾在低湍流风中的表现 我现在遇到的一些问题是 颗粒聚集成一个大球 粒子扩散到无限远 粒子突然弹射离开 我已经完成
  • 为什么 cuCtxCreate 返回旧上下文?

    我已经安装了 CUDA SDK 4 2 64 CUDA工具包4 2 64 CUDA 驱动程序 4 2 64 我检查了 windows 中的每个 nvcuda dll 所有这些都是 4 2 版本 但是当我使用驱动程序 api 创建上下文并使用
  • 如何在CUDA应用程序中正确应用线程同步?

    一般来说 我在应用程序中偶尔会使用线程同步 因为我并不经常需要此功能 我并不是真正的高级 C C 程序员 但我也不是初学者 我开始学习 CUDA C 对当今 GPU 与 CPU 的能力相比感到兴奋 我意识到 CUDA 编程主要是关于并行线程
  • CUDA 添加矩阵的行

    我试图将 4800x9600 矩阵的行加在一起 得到一个 1x9600 的矩阵 我所做的是将 4800x9600 分成 9 600 个矩阵 每个矩阵长度为 4800 然后我对 4800 个元素进行缩减 问题是 这真的很慢 有人有什么建议吗
  • CUDA 的嵌套循环

    我想将我的 C 代码移植到 CUDA 主要计算部分包含3个for嵌套循环 for int i 0 i lt Nx i for int j 0 j
  • CUDA 模型 - 什么是扭曲尺寸?

    最大工作组大小和扭曲大小之间有什么关系 假设我的设备有 240 个 CUDA 流处理器 SP 并返回以下信息 CL DEVICE MAX COMPUTE UNITS 30 CL DEVICE MAX WORK ITEM SIZES 512
  • 为什么 cudaGLSetGLDevice 失败,即使它是在 main 函数的第一行中调用的

    我想使用 OpenGL 和 CUDA 之间的互操作性 我知道 正如一些教程所说 第一步是选择设备 但是 当我在主函数的第一行中调用 cudaGLSetGLDevice 0 时 程序退出并显示信息 cudaSafeCall 运行时 API 错
  • 如何安装libcusolver.so.11

    我正在尝试安装 Tensorflow 但它要求 libcusolver so 11 而我只有 libcusolver so 10 有人可以告诉我我做错了什么吗 这是我的 Ubuntu nvidia 和 CUDA 版本 uname a Lin
  • 直接在主机上访问设备向量元素的最快方法

    我请您参考以下页面http code google com p thrust wiki QuickStartGuide Vectors http code google com p thrust wiki QuickStartGuide V
  • CUDA-Kernel 应该根据块大小动态崩溃

    我想做稀疏矩阵 密集向量乘法 假设用于压缩矩阵中条目的唯一存储格式是压缩行存储 CRS 我的内核如下所示 global void krnlSpMVmul1 float data mat int num nonzeroes unsigned
  • cudaMalloc使用向量>进行管理 > C++ - NVIDIA CUDA

    我正在通过 NVIDIA GeForce GT 650M GPU 为我创建的模拟实现多线程 为了确保一切正常工作 我创建了一些辅助代码来测试一切是否正常 在某一时刻 我需要更新变量向量 它们都可以单独更新 这是它的要点 device int
  • 为什么使用 boost::none 无法通过 nvcc 编译?

    我正在尝试编译以下代码 include
  • 如何降级cuda版本

    我目前使用的是 cuda 版本 4 2 但我需要将其更改为 3 1 是否可以卸载当前版本 4 2 版 然后安装以前的版本 3 1 版 编辑 请参阅我的操作系统是linux ubuntu 10 04 64位 编辑 我找到了如何获取 3 1 版
  • 如何转储所有 NVCC 预处理器定义?

    我想达到同样的效果 gcc dM E lt dev null 如所描述的here https stackoverflow com q 2224334 1593077 但对于 nvcc 也就是说 我想转储所有 nvcc 的预处理器定义 唉 n
  • 需要 TensorFlow 依赖项。如何在 Windows 上运行 TensorFlow

    我有兴趣让 TensorFlow 在 Windows 上运行 但目前我意识到这是不可能的 因为某些依赖项无法在 Windows 上使用 例如巴泽尔 之所以出现这种需求 是因为据我目前了解 从 TensorFlow 访问 GPU 的唯一方法是
  • 使用设备函数指针数组

    我需要以下设备版本 主机代码 double func double x double func1 double x return x 1 double func2 double x return x 2 double func3 doubl
  • 如何使用 Visual Studio 2008 调试 CUDA 内核代码?

    嘿 我正在使用带有 CUDA 3 2 的 Visual Studio 2008 我正在尝试调试具有此签名的函数 MatrixMultiplication Kernel lt lt
  • 如何使用Slurm访问集群中不同节点上的GPU?

    我可以访问由 Slurm 运行的集群 其中每个节点都有 4 个 GPU 我有一个需要 8 个 GPU 的代码 那么问题是 如何在每个节点只有 4 个 GPU 的集群上请求 8 个 GPU 这就是我尝试通过以下方式提交的工作sbatch bi

随机推荐

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

    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