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

标签 c++ multithreading cpu hpc slurm

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

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

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

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

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

#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 个 CPU,但机器总共有 32 个 CPU。

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

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

最佳答案

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

您可以使用std::getenv获取环境变量的值。它返回一个 char * 并且您需要诸如 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。

关于c++ - SLURM C++ 发现可用内核多于分配的内核,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57834339/

相关文章:

c++ - 具有折叠表达式的模板会创建不需要的参数拷贝

c++ - 在 Qt 中压缩一个 .txt 文件

c - 是否有官方文档将读/写函数标记为线程安全函数?

Javascript THREEJS 和 GC

c++ - 为什么将 CString 转换为 wchar_t* 会产生一个临时拷贝?如果我们使用其他类型而不是 CString 会怎样?

c++ - 仅提供宽字符串逻辑字符串比较的动机

multithreading - 多个线程在单个套接字或管道上执行 poll() 或 select()

java - Android 多线程应用程序崩溃

assembly - 哪些指令会在 x86 CPU 上产生分支预测错误?

javascript - 如何使用 Javascript 测试用户计算机的处理能力?