这在一定程度上取决于您正在考虑的 OpenMP 版本/功能,因为我相信更高版本可能会为您提供更多功能,但原始库是围绕数据并行构建的for
原语。一般来说,OpenMP 和其他数据并行编程模型尝试抽象底层硬件,程序员将其计算声明为对数据的一系列操作,然后由 OMP 调度。
为了回答您的第一个问题,操作系统调度程序将跨内核调度线程,OMP 调度程序将跨可用线程调度工作。
#pragma omp parallel for
for (i = 0; i < N; i++)
a[i] = 2 * i;
OMP 调度程序将根据许多因素(包括负载、分配给它的工作量以及您可能提供的任何提示)来选择要使用的核心(真实核心或超线程)。人们期望上面的代码能够在所有可用核心上运行(在您的示例中为 4 个)
您可以使用schedule
关键字控制调度程序如何分配工作。
时间表(类型,块):如果工作共享结构是这样的话,这很有用
do 循环或 for 循环。工作共享结构中的迭代
根据定义的调度方法分配给线程
这个条款。三种类型的调度是:
static:在这里,所有
线程在执行循环之前被分配迭代
迭代。迭代在线程之间平均分配
默认。但是,为参数块指定一个整数将
将连续迭代的块数分配给特定线程。
dynamic:这里,一些迭代被分配给较小的迭代
线程数。一旦特定线程完成其分配的
迭代,它返回以从迭代中获取另一个迭代
左边。参数chunk定义了连续迭代的次数
一次分配给一个线程。
guided:一大块
连续的迭代被动态地分配给每个线程(如
多于)。块大小随着每个连续的指数而减小
分配到参数块中指定的最小大小
From 维基百科
回答你的第二个问题。您还可以使用num_threads
属性指定要使用的线程数。在上面添加以下内容#pragma omp parallel for
在该示例中,会将 OMP 限制为三个线程,无论是否有更多线程可用。
#pragma omp parallel num_threads(3)
#pragma omp for
for (i = 0; i < N; i++)
a[i] = 2 * i;
还可以在某种程度上控制多处理器(多个插槽)系统中不同处理器之间的工作调度方式。OpenMP 和 NUMA 的关系?
您可能还会发现以下指南很有用,OpenMP 指南:C++ 的简单多线程编程.