Cluster computing OpenMP线程如何映射到作业调度器(例如:LSF)分配的特定内核?

Cluster computing OpenMP线程如何映射到作业调度器(例如:LSF)分配的特定内核?,cluster-computing,openmp,job-scheduling,lsf,Cluster Computing,Openmp,Job Scheduling,Lsf,当使用作业调度器运行程序时,调度器会为作业分配n个处理器内核(由用户指定)。当使用OpenMP的程序运行时,OpenMP通常会使用OMP_NUM_线程,为了简单起见,我们会说每个线程都映射到不同的处理器核心 OpenMP不知道调度程序(afaik)将哪些内核分配给程序/作业。此外,操作系统实际上是将OpenMP线程映射到核心的,而不是OpenMP 我的问题是:在幕后发生了什么,使得OpenMP线程只映射到由作业调度器分配给作业的内核 我希望我的问题是一般性的,但是如果进程在作业调度器之间确实不同

当使用作业调度器运行程序时,调度器会为作业分配n个处理器内核(由用户指定)。当使用OpenMP的程序运行时,OpenMP通常会使用OMP_NUM_线程,为了简单起见,我们会说每个线程都映射到不同的处理器核心

OpenMP不知道调度程序(afaik)将哪些内核分配给程序/作业。此外,操作系统实际上是将OpenMP线程映射到核心的,而不是OpenMP

我的问题是:在幕后发生了什么,使得OpenMP线程只映射到由作业调度器分配给作业的内核


我希望我的问题是一般性的,但是如果进程在作业调度器之间确实不同,那么LSF特定的答案将是最好的。

它的工作方式非常简单-DRM(分布式资源管理器)在进程启动之前限制进程的CPU关联掩码。关联掩码告诉OS调度器进程可以调度在哪个逻辑CPU上。默认CPU关联掩码仅包含所有可用的逻辑CPU。如果没有其他指示,大多数OpenMP运行时会在程序启动时获得该掩码,并在生成新线程时遵守该掩码。如果未指定任何
OMP\u NUM\u线程,GNU和英特尔OpenMP运行时都会检查关联掩码,以确定默认的线程数。大多数OpenMP运行时还支持自己的绑定机制(也称为按线程关联),例如英特尔OpenMP的
KMP\u关联
变量或GNU OpenMP的
GOMP\u CPU\u关联
变量。可以指示其中一些线程遵守原始掩码,例如,
KMP\u AFFINITY=“尊重,粒度=核心”
将使Intel OpenMP仅将其线程绑定到启动进程的关联掩码中启用的CPU

在Linux下,有两种关联掩码。一个可以被认为是软的,由
sched\u setaffinity(2)
syscall设置。此掩码是软的,因为它可以随时被覆盖和扩展。但是Linux也提供了所谓的cpusets(cgroups框架的一部分),其功能或多或少类似于轻量级容器。可以创建一个cpuset,并仅将某些逻辑CPU分配给它,然后通过
sched_setaffinity()
使用请求的任何掩码对该集合进行加密,以获得实际应用的最终掩码。因此,cpusets提供了一个硬屏蔽——它不能被扩展,而只能使用它或它的子集(而不是超集)sched_setaffinity()
采用PID或TID,因此可用于设置单个线程的关联,这就是OpenMP运行时实现每个线程关联的方式。更方便的调用是POSIX
pthread\u setaffinity\u np()

LSF(9.1.1及更高版本)支持使用Linux cpusets进行关联。如果您是LSF管理员,请参阅有关如何设置的文档;如果您是用户,请参阅有关如何为作业请求某些关联设置的文档


如果我没记错的话,Sun(呃…我是说Oracle)网格引擎从版本6.2u5开始就对流程关联提供了一些支持。

只是为了确保我清楚这一点。。。作业调度器在进程开始使用特定于操作系统的系统调用时设置CPU相关性。所以这与OpenMP没有任何关系。与此不同,OpenMP还具有实现特定的功能,允许程序员设置CPU相关性。由于作业计划程序使用硬掩码(cpuset),而OpenMP使用软掩码,因此程序将在cpuset关联掩码和软关联掩码(来自OpenMP)中包含的处理器上运行。这听起来对吗?谢谢你的帮助!您的理解是正确的,但是一些作业调度程序在Linux上不使用cpusets,并且它们设置的掩码不是“硬”的,因此很容易被OpenMP运行时覆盖,因此在此类环境中必须格外小心(例如,在英特尔OpenMP运行时的
KMP\u AFFINITY
中包含
尊重
关键字)。OpenMP 4.0包含位置的概念,这些位置是指定绑定的标准化机制。