SLURM C++ 发现可用内核多于分配的内核

SLURM C++ sees more cores available than assigned

我正在尝试 运行 SLURM 管理的 HPC 集群上的单进程多线程作业。我打算为我的线程使用多核。

当我将资源分配给 HPC 时,我使用命令:

#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=8

这应该为同一台机器上的一个进程分配 8 CPUs,对吧?

但是,当我尝试使用以下代码检测可用内核数时:

#include <iostream>
#include <thread>

int main() {
    unsigned int n = std::thread::hardware_concurrency();
    std::cout << n << " concurrent threads are supported.\n";
}

它输出:

32 concurrent threads are supported.

这很奇怪,因为我希望它输出支持 8 个并发线程。我怀疑,尽管 SLURM 只为任务分配了 8 CPUs,但机器总共有 32 CPUs。

但是,我使用的某些包依赖于hardware_concurrency命令来获取CPU的数量。因此,这可能会导致某些包因线程过多而使系统过载。

  1. 知道为什么吗?
  2. 您认为我的帐户会为这项工作收取 32 CPU 个时钟,而不是 8 个吗?
  3. 我是否应该将应用程序中的线程数限制为我分配的内核数 (8),而不是 C++ 检测到的内核数 (32),以实现最高效率?
  4. 您知道任何报告 SLURM 分配的正确 CPU 可用数量(不是机器中 CPU 的总数)的 c++ 代码吗?

即使依赖硬件并发的包,通常也是获取线程数的默认值。它很可能还为您提供了一种自行设置所需值的方法。如果是这种情况,那么您可以使用环境变量从 slurm 中获取分配给您的作业的 CPU 数量。在您的特定情况下,环境变量是 SLURM_CPUS_PER_TASK.

您可以使用 std::getenv to get the value of an environment variable. It returns a char * and you need something such as std::atoi 将其转换为 int

#include <iostream>
#include <thread>
#include <cstdlib>

int main() {
    unsigned int n = std::thread::hardware_concurrency();
    std::cout << n << " concurrent threads are supported.\n";

    std::cout << "CPUS_PER_TASK: " << std::atoi(std::getenv("SLURM_CPUS_PER_TASK")) << std::endl;
}

如果您不这样做,那么 C++ 程序将创建 32 个线程,但 slurm 仍应将您的作业限制为 8 个内核。因此,每个线程将只使用大约 25% 的 CPU。