同时使用 2 个 GPU 调用 cudaMalloc 时性能较差

2024-04-19

我有一个应用程序,可以在用户系统上的 GPU 之间分配处理负载。基本上,每个 GPU 都有一个 CPU 线程来启动一个GPU处理间隔当由主应用程序线程定期触发时。

考虑以下图像(使用 NVIDIA 的 CUDA 分析器工具生成)作为示例GPU处理间隔-- 这里应用程序使用单个 GPU。

如您所见,两个排序操作消耗了很大一部分 GPU 处理时间,我为此使用 Thrust 库 (thrust::sort_by_key)。另外,看起来 Thrust::sort_by_key 在开始实际排序之前会在后台调用一些 cudaMalloc。

现在考虑相同的处理间隔,其中应用程序将处理负载分散到两个 GPU 上:

在理想情况下,您会期望 2 个 GPU 处理间隔恰好是单个 GPU 处理间隔的一半(因为每个 GPU 执行一半的工作)。正如您所看到的,情况并非如此,部分原因是由于某种争用问题,同时调用 cudaMalloc 时它们似乎需要更长的时间(有时长 2-3 倍)。我不明白为什么需要这样,因为 2 个 GPU 的内存分配空间是完全独立的,所以 cudaMalloc 上不应该有系统范围的锁——每个 GPU 的锁会更合理。

为了证明我的假设(问题在于同时调用 cudaMalloc),我创建了一个极其简单的程序,其中有两个 CPU 线程(针对每个 GPU),每个线程调用 cudaMalloc 多次。我首先运行这个程序,以便单独的线程不会同时调用 cudaMalloc:

您会看到每次分配大约需要 175 微秒。接下来,我使用同时调用 cudaMalloc 的线程运行该程序:

在这里,每个调用花费了大约 538 微秒,或者说比之前的情况长了 3 倍!不用说,这极大地减慢了我的应用程序的速度,而且按理说,如果 GPU 数量超过 2 个,问题只会变得更糟。

我在 Linux 和 Windows 上注意到了这种行为。在 Linux 上,我使用 Nvidia 驱动程序版本 319.60,在 Windows 上我使用 327.23 版本。我正在使用 CUDA 工具包 5.5。

可能的原因:我在这些测试中使用的是 GTX 690。该卡基本上是将 2 680 个类似 GPU 安置在同一单元中。这是我运行过的唯一“多 GPU”设置,所以也许 cudaMalloc 问题与 690 的 2 个 GPU 之间的某些硬件依赖性有关?


我将在前面声明一个免责声明:我不了解 NVIDIA 驱动程序的内部结构,因此这有些推测性。

您看到的速度减慢只是由同时调用设备 malloc 的多个线程竞争引起的驱动程序级别争用。设备内存分配需要许多操作系统系统调用,驱动程序级别上下文切换也是如此。这两个操作都存在相当大的延迟。当两个线程尝试同时分配内存时,您看到的额外时间很可能是由在两个设备上分配内存所需的系统调用序列中从一个设备切换到另一个设备的额外驱动程序延迟引起的。

我可以想到一些可以减轻这种情况的方法:

  • 您可以减少推力内存分配的系统调用开销 通过编写您自己的自定义推力内存分配器来为零 使用期间分配的一块内存工作的设备 初始化。这将消除所有系统调用开销 每个内sort_by_key,但是编写自己的用户的努力 内存管理器并不简单。另一方面它留下了其余的 你的推力代码完好无损。
  • 您可以切换到替代排序库并收回 自己管理临时内存的分配。如果你做了所有的 在初始化阶段分配,一次性的成本 内存分配在整个生命周期内可以摊销到几乎为零 每个线程。

在我编写的基于多 GPU CUBLAS 的线性代数代码中,我结合了这两种想法并编写了一个独立的用户空间设备内存管理器,该管理器在一次性分配的设备内存池上工作。我发现消除中间设备内存分配的所有开销成本可以带来有用的加速。您的用例might从类似的策略中受益。

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

同时使用 2 个 GPU 调用 cudaMalloc 时性能较差 的相关文章

  • CUDA线程执行顺序

    我有一个 CUDA 程序的以下代码 include
  • 并行处理的ThreadPool和Pool

    有没有办法在 python 中同时使用 ThreadPool 和 Pool 来通过指定您希望使用的 CPU 和内核的数量来并行循环 例如 我将循环执行为 from multiprocessing dummy import Pool as T
  • Nvcc 的版本与 CUDA 不同

    我安装了 cuda 7 但是当我点击 nvcc version 时 它打印出 6 5 我想在 GTX 960 卡上安装 Theano 库 但它需要 nvcc 7 0 我尝试重新安装cuda 但它没有更新nvcc 当我运行 apt get i
  • 如何在 CUDA 中执行多个矩阵乘法?

    我有一个方阵数组int M 10 以便M i 定位第一个元素i th 矩阵 我想将所有矩阵相乘M i 通过另一个矩阵N 这样我就收到了方阵数组int P 10 作为输出 我看到有不同的可能性 分配不同元素的计算M i 到不同的线程 例如 我
  • 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
  • MongoDB:在没有并行性的情况下使用 MapReduce 有什么意义?

    Quoting http www mongodb org display DOCS MapReduce MapReduce Parallelism http www mongodb org display DOCS MapReduce Ma
  • shell进程的并行执行

    有没有一个工具可以在 Windows 批处理文件中并行执行多个进程 我发现了一些有趣的 Linux 工具 parallel http mi eng cam ac uk er258 code parallel html and PPSS ht
  • Random 并行生成数字 1 的次数超过 90% [重复]

    这个问题在这里已经有答案了 考虑以下程序 public class Program private static Random rnd new Random private static readonly int ITERATIONS 50
  • fork() 不并行运行

    我对编程过程很陌生 我的基本程序并没有真正按照我的预期工作 我在 Oracle VM 上的 Ubuntu 18 04 上运行此代码 这是代码 include
  • ElasticSearch 多滚动 Java API

    我想从索引中获取所有数据 由于项目数量对于内存来说太大 我使用滚动 很好的功能 client prepareSearch index setTypes myType setSearchType SearchType SCAN setScro
  • 如何在cmake中添加cuda源代码的定义

    我使用的是 Visual Studio 2013 Windows 10 CMake 3 5 1 一切都可以使用标准 C 正确编译 例如 CMakeLists txt project Test add definitions D WINDOW
  • 在 cudaFree() 之前需要 cudaDeviceSynchronize() 吗?

    CUDA 版本 10 1 帕斯卡 GPU 所有命令都发送到默认流 void ptr cudaMalloc ptr launch kernel lt lt lt gt gt gt ptr cudaDeviceSynchronize Is th
  • Tensorflow:docker 镜像和 -gpu 后缀

    在具有 GPU 支持的 Tensorflow 的 Docker 映像中 例如 tensorflow tensorflow 2 2 0 gpu 安装的python包是tensorflow gpu 如图所示pip freeze 安装任何依赖于的
  • Java 中的并行编程

    我们如何在Java中进行并行编程 有什么特殊的框架吗 我们怎样才能让这些东西发挥作用 我会告诉你们我需要什么 认为我开发了一个网络爬虫 它从互联网上爬取了大量数据 一个爬行系统无法使事情正常工作 因此我需要更多的系统并行工作 如果是这种情况
  • NV_path_rendering替代方案[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我刚刚观看了 Siggraph 2012 的一个非常令人印象深刻的演示 http nvidia fullviewmedia com sig
  • 我可以在 R 中并行读取 1 个大 CSV 文件吗? [复制]

    这个问题在这里已经有答案了 我有一个很大的 csv 文件 需要很长时间才能阅读 我可以使用 parallel 或相关的包在 R 中并行读取此内容吗 我尝试过使用 mclapply 但它不起作用 根据OP的评论 fread来自data tab
  • 处理异步并行任务的多个异常

    Problem 多个任务并行运行 所有任务 没有任务或其中任何任务都可能抛出异常 当所有任务完成后 必须报告所有可能发生的异常 通过日志 电子邮件 控制台输出 等等 预期行为 我可以通过 linq 使用异步 lambda 构建所有任务 然后
  • 并行模拟写入同一文件

    我的目标是在集群上并行运行 10 000 个左右的 Julia 编码模拟 每个模拟独立于所有其他模拟 每个模拟都有一个要输出的数字 以及有关哪个模拟产生该数字的 3 列信息 因此 强制每个模拟打印在单独的文件上对我来说听起来有点愚蠢 我可以
  • Parallel.For 和 Break() 误解?

    我正在研究 For 循环中的并行性中断 看完之后this http tipsandtricks runicsoft com CSharp ParallelClass html and this http reedcopsey com 201

随机推荐

  • WIQL 查询获取项目中的所有团队和用户?

    let s say i have a project name Scrum and that has some users the project and got sprints so i want dstinct users of the
  • HttpConfiguration.get_ServiceResolver() 丢失

    我正在将 Ninject 与 MVC4 连接起来 并使其工作到尝试实际解决依赖关系的程度 但是 我收到以下异常 找不到方法 System Web Http Services DependencyResolver System Web Htt
  • Java 构造函数内部的多态性

    Code class A A test void test System out println from A class B extends A void test System out println from B class C pu
  • Google App Engine 的简单用户管理示例?

    我是 Google App Engine 的新手 当我学习本教程时 我发现我们在 php mysql 中所做的一些事情在 GAE 中不可用 例如 在 dataStore 中 自动增量功能不可用 我也对 GAE 中的会话管理感到困惑 总的来说
  • 在对象为布尔值的情况下,Javascript 中如何进行类型强制转换?

    尽我所知 x false 应该做同样的事情 x 因为他们都试图解释x作为布尔值 然后对其求反 然而 当我尝试对此进行测试时 我开始出现一些极其奇怪的行为 例如 false and false 两者都返回 true 此外 false unde
  • 内核虚拟地址转换

    考虑到 Linux 和 32 位 x86 架构 可访问的 4GB 地址空间的比例为 3 1 用户空间分配0 3 Gb 而3 4 Gb 分配给内核 大于 3Gb 且位于内核地址空间的虚拟地址如何转换为物理地址 页表会出现吗 梅尔 戈尔曼的书中
  • 如何列出泽西岛所有注册的 JAX-RS 实体提供商

    假设我有一个带有嵌入式码头的简单球衣应用程序github上的演示项目 https github com varren jersey2 gradle embedded jetty demo repo和下面的基本代码 回到 jersey1 的日
  • Android Studio 在运行测试时不使用 Gradle jvmArgs?

    我有一个带有 JUnit 测试的 Android 库 只有在使用 noverify标志传递给 JVM 我相信是因为this https stackoverflow com a 15122960 1910286 如果从命令行运行测试就会通过
  • 当我有表面声明时,如何为 sm_1X 和 sm_2X 编译 CUDA 程序

    我正在编写一个使用表面 重新采样并写入纹理 来提高性能的库 surface
  • 每行熊猫都会在下周日返回

    在 Pandas for Python 中 我有一个数据集 其中有一列日期时间 我需要创建一个新列 其中每行包含下周日的日期 我尝试过各种方法尝试使用 iterrows 然后计算出一周中的某一天 并添加一天直到该天为 7 但它没有起作用 我
  • GNUPLOT 绘制 5 天的财务周

    我已经寻找了一段时间 以找出如何从财务图中删除一周中的几天 但没有成功 我需要该图仅包含一周中的几天并完全忽略周末 以便财务图表中没有 2 天的差距 我有 CSV 格式的开盘 低 收盘 高数据 并且缺少周末数据 它绘制得很好 但我找不到如何
  • CoroutineScope.async 上的异常传播如何工作?

    我看到多个消息来源声称 async 块内发生的异常不会传递到任何地方 仅存储在Deferred实例 声称该异常仍然是 隐藏的 并且仅在人们调用时影响外部事物await 这通常被描述为之间的主要区别之一launch and async 这是一
  • 创建Flutter项目时出现权限错误

    我是 Flutter 新手 安装后 当我尝试创建项目时出现此错误 hello world flutter create ios language swift android language kotlin Failed to open or
  • 如何在 Javafx 中将文本插入到形状中?

    我使用 JavaFX 创建了一个简单的矩形对象 我希望能够将文本对象放入该矩形内 并使其自动在矩形内保持对齐 我必须绘制矩形的代码是 public static Scene createScene Group root new Group
  • 科尔多瓦应用程序中的输入类型=“文件”替代方案

    我正在开发一个科尔多瓦 Android 应用程序 但是input type file 在那里不起作用 我应该使用哪种替代方法才能在加载文件之前看到提示窗口 None
  • 如何在 C# 中保存电子邮件附件 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 如何使用 C 从我的邮件 例如 gm
  • React-router-redux 在链接上单击两次即可更新位置状态

    我的应用程序出现问题 无法在任何地方找到解决方案 我用react router redux and syncHistoryWithStore 当我单击导航以使用链接更改路线时 新路线会加载 浏览器中的 URL 会更新 但是location除
  • 有没有更好的方法将多值数据显示为列?

    我的笔记数据库中有 4 个审核字段 它们是多值的 当表单上的某些内容发生更改时 它们都会获得一个新条目 我有一个审核表单 以柱状方式显示这些字段 几乎就像一个视图 这是列的代码
  • 返回响应后如何记录 POST 方法的返回值?

    我正在开发我的第一个 REST API 所以如果我错过了一些基本的东西 请提前道歉 我有一个函数 它从另一台服务器获取 JSON 请求 对其进行处理 根据数据进行预测 然后返回另一个带有结果的 JSON 我想在服务器的本地磁盘上保留对此端点
  • 同时使用 2 个 GPU 调用 cudaMalloc 时性能较差

    我有一个应用程序 可以在用户系统上的 GPU 之间分配处理负载 基本上 每个 GPU 都有一个 CPU 线程来启动一个GPU处理间隔当由主应用程序线程定期触发时 考虑以下图像 使用 NVIDIA 的 CUDA 分析器工具生成 作为示例GPU