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的数量。因此,这可能会导致某些包因线程过多而使系统过载。
- 知道为什么吗?
- 您认为我的帐户会为这项工作收取 32 CPU 个时钟,而不是 8 个吗?
- 我是否应该将应用程序中的线程数限制为我分配的内核数 (8),而不是 C++ 检测到的内核数 (32),以实现最高效率?
- 您知道任何报告 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。
我正在尝试 运行 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的数量。因此,这可能会导致某些包因线程过多而使系统过载。
- 知道为什么吗?
- 您认为我的帐户会为这项工作收取 32 CPU 个时钟,而不是 8 个吗?
- 我是否应该将应用程序中的线程数限制为我分配的内核数 (8),而不是 C++ 检测到的内核数 (32),以实现最高效率?
- 您知道任何报告 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。