parallel-processing - 同时在所有 GPU 内核上为每个 GPU 内核运行一个程序实例
问题描述
我们有数以百万计的小文件要由某些程序处理。
精确的程序并不重要,并且也会随着精确的任务而变化。然而,这些是较小的 C++ 程序,我们有源代码,但它们本质上不是可并行化的。
使用单个平均 CPU 内核(Intel i7 系列)时,处理一个小文件大约需要 15 秒。并且在程序运行时它需要大约 200 MB 的 RAM。
我们希望在 GPU 上并行化,并在每个 GPU 核心(例如 Cuda 核心)上运行一个程序实例。因此,如果 GPU 有 3000 个 CUDA 核心,那么我们希望并行运行 3000 个实例。如果可能的话,我们想使用像 OpenCL 这样的通用框架(而不是 Cuda,但如果这种情况需要 Cuda,这是可以接受的)。
现在我们正在尝试评估这是否可能(我们对 GPGPU 编程还没有太多经验)。我们想象的主要问题是内存。如果我们并行运行 3000 个实例,每个实例需要 200 MB VRAM,那么我们需要 600 GB 内存。
我们主要想到的显卡是高端 Geforce 卡,通常有 8 GB 到 11 GB 的内存。我们有 GPU 工作站,每个机箱/主板有 4 个卡,我们一开始希望使用它(但后来也可能在其他 GPU 系统上,因此我们更喜欢像 OpenCL 这样的通用框架)。
有哪些方法可以解决这个问题?
解决方案
精确的程序并不重要
这是一厢情愿的想法。您要解决的问题非常重要;如果它像将 C++ 代码重新编译为 GPU 着色器二进制文件一样简单,那么几乎所有软件都会这样做以免费提高速度。
您通常无法将整个 C++ 程序 1:1 转换为 GPU 内核,即使您设法做到了,它的性能也会非常糟糕。你真的需要努力从 SIMD 类型的操作角度重新思考你的问题,以便在 GPU 上取得任何进展。
特别是,您似乎认为每个 GPU“核心”都是独立的。情况并非如此,它们中的一些组步调一致地工作,因此如果您的代码是分支繁重的,那么您的利用率将非常低。它们还共享内存总线,因此如果每个线程访问不相关的内存区域,这将大大减慢执行速度,并且您将无法足够快地为 ALU/FPU 提供数据。
内存也是一个问题,但不仅仅是因为您指出的 VRAM 总量,还因为局部变量使用“私有”内存,这实际上是寄存器,并且是非常有限的资源(以千字节为单位)最好的)。
我建议查看所有主要 GPU 供应商发布的 OpenCL 优化指南。这将使您很好地了解哪种代码性能良好,哪些代码性能不佳,以及在决定将哪些代码卸载到 GPU 以及如何卸载时需要考虑哪些因素。
推荐阅读
- r - 使用 pickerInput 选择最多 2 个不同的组
- javascript - 如何从另一个组件更改反应组件的状态
- angular - 反应形式正在验证列表中的所有迭代
- android - 为什么我的工具栏在滚动时没有折叠?
- python - 将字典列表合并到 json
- javafx - JavaFX DatePicker 禁用未来日期
- sql - BigQuery 上的自定义 SQL 中的自定义列
- python-3.x - 我想通过递归返回 n 中所有索引的总和。我该怎么做呢?
- neo4j - Neo4J 在线备份——有什么方法可以解决安全漏洞?
- python-3.x - numpy 数组在更改值后显示相同的 id