是否可以在多GPU机器上执行CUDA程序的多个实例?

ase*_*eal 3 c++ cuda gpu multi-gpu

背景:

我编写了一个CUDA程序,对一系列符号进行处理.该程序并行处理所有符号序列,并规定所有序列具有相同的长度.我正在将我的数据分组,每组完全由相同长度的序列组成.该程序一次处理1个组.

题:

我在具有4个GPU的Linux机器上运行我的代码,并希望通过运行我的程序的4个实例(每个GPU 1个)来利用所有4个GPU.是否可以让程序选择另一个CUDA应用程序未使用的GPU来运行?当程序在具有更多或更少GPU的不同硬件上运行时,我不想硬编码会导致问题的任何事情.

Rob*_*lla 5

环境变量 CUDA_VISIBLE_DEVICES是你的朋友.

我假设您拥有与GPU一样多的终端.假设您的应用程序被调用myexe

然后在一个终端,您可以:

CUDA_VISIBLE_DEVICES="0" ./myexe
Run Code Online (Sandbox Code Playgroud)

在下一个终端:

CUDA_VISIBLE_DEVICES="1" ./myexe
Run Code Online (Sandbox Code Playgroud)

等等.

然后第一个实例将在CUDA枚举的第一个GPU上运行.第二个实例将在第二个GPU(仅)上运行,依此类推.

假设bash,对于给定的终端会话,您可以通过导出变量使其成为"永久":

export CUDA_VISIBLE_DEVICES="2"
Run Code Online (Sandbox Code Playgroud)

此后,在该会话中运行的所有CUDA应用程序将仅观察到第三个枚举的GPU(枚举从0开始),并且他们将观察到GPU ,就好像它们在会话中是设备0一样.

这意味着您不必对此方法的应用程序进行任何更改,假设您的应用程序使用默认的GPU或GPU 0.

您还可以对此进行扩展以使多个GPU可用,例如:

export CUDA_VISIBLE_DEVICES="2,4"
Run Code Online (Sandbox Code Playgroud)

通常枚举为2和4的GPU现在是该会话中唯一"可见"的GPU,它们将枚举为0和1.

在我看来,上述方法是最简单的.选择"未使用"的GPU是有问题的,因为:

  1. 我们需要"使用中"的定义
  2. 在特定时刻使用的GPU可能在此之后不会立即使用
  3. 最重要的是,没有"正在使用"的GPU可能会异步"使用",这意味着您将面临竞争条件.

因此,最好的建议(IMO)是明确管理GPU.否则,您需要某种形式的作业调度程序(在此问题的范围之外,IMO)能够查询未使用的GPU并在另一个应用程序尝试之前"保留"一个,以有序的方式.