代码之家  ›  专栏  ›  技术社区  ›  Steve

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

  •  1
  • Steve  · 技术社区  · 12 年前

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

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

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

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

    1 回复  |  直到 12 年前
        1
  •  3
  •   Hristo Iliev    12 年前

    它的工作方式非常简单——DRM(分布式资源管理器)在进程启动之前限制进程的CPU关联掩码。关联掩码告诉操作系统调度程序可以在哪些逻辑CPU上调度进程。默认的CPU关联掩码只包含所有可用的逻辑CPU。如果没有其他指示,大多数OpenMP运行时在程序启动时获得该掩码,并在生成新线程时遵守该掩码。GNU和Intel OpenMP运行时都会检查关联掩码,以确定默认线程数(如果没有) OMP_NUM_THREADS 已指定。大多数OpenMP运行时还支持自己的绑定机制(也称为每线程亲和性),例如 KMP_AFFINITY Intel OpenMP变量或 GOMP_CPU_AFFINITY GNU OpenMP的变量。其中一些可以被指示尊重原始掩模,例如。 KMP_AFFINITY="respect,granularity=core" 将使Intel OpenMP仅将其线程绑定到进程启动时的关联掩码中启用的CPU。

    在Linux下有两种亲和掩码。一个可以被认为是软的,由 sched_setaffinity(2) 系统调用。此掩码是软的,因为它可以随时被覆盖和展开。但Linux也提供了所谓的cpusets(cgroups框架的一部分),其功能或多或少类似于轻量级容器。可以创建一个cpuset,并仅为其分配特定的逻辑CPU,然后通过 sched_setaffinity() 以便获得实际应用的最终掩模。因此,cpusets提供了一个硬掩码-它不能扩展,只能使用它或它的子集(但不能使用超集)。 sched_setAfinity() 在Linux上采用PID或TID,因此可以用于设置单个线程的关联性,这就是OpenMP运行时实现每线程关联性的方式。一个更便携的电话是POSIX pthread_setaffinity_np() .

    LSF(9.1.1及更高版本)支持使用Linux cpusets的亲和性。请参阅文档 here 如果您是LSF管理员,如何设置它;如果您是用户,如何请求作业的特定关联设置。

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