首页 > 解决方案 > 同时在所有 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 这样的通用框架)。

有哪些方法可以解决这个问题?

标签: parallel-processingcudaopenclgpgpu

解决方案


精确的程序并不重要

这是一厢情愿的想法。您要解决的问题非常重要;如果它像将 C++ 代码重新编译为 GPU 着色器二进制文件一样简单,那么几乎所有软件都会这样做以免费提高速度。

您通常无法将整个 C++ 程序 1:1 转换为 GPU 内核,即使您设法做到了,它的性能也会非常糟糕。你真的需要努力从 SIMD 类型的操作角度重新思考你的问题,以便在 GPU 上取得任何进展。

特别是,您似乎认为每个 GPU“核心”都是独立的。情况并非如此,它们中的一些组步调一致地工作,因此如果您的代码是分支繁重的,那么您的利用率将非常低。它们还共享内存总线,因此如果每个线程访问不相关的内存区域,这将大大减慢执行速度,并且您将无法足够快地为 ALU/FPU 提供数据。

内存也是一个问题,但不仅仅是因为您指出的 VRAM 总量,还因为局部变量使用“私有”内存,这实际上是寄存器,并且是非常有限的资源(以千字节为单位)最好的)。

我建议查看所有主要 GPU 供应商发布的 OpenCL 优化指南。这将使您很好地了解哪种代码性能良好,哪些代码性能不佳,以及在决定将哪些代码卸载到 GPU 以及如何卸载时需要考虑哪些因素。


推荐阅读