OMP 调度有 4 种类型。它们是静态的、动态的、运行时的和引导的。每种调度都有其优点。调度的存在是为了更好地平衡线程之间的负载。
我会给你一些静态和动态调度的例子。引导也是类似的。
schedule(runtime) 子句告诉它使用环境变量设置调度。环境变量可以设置为任何其他调度类型。可以设置
setenv OMP_SCHEDULE “dynamic,5”
静态调度
当您知道每个线程将在编译时或多或少地执行相同数量的工作时,使用静态调度。
例如,可以使用 OMP 并行化以下代码。假设我们只使用 4 个线程。
如果我们使用默认的静态调度并将 pragma 放在外部 for 循环中,那么每个线程将执行 25% 的外部循环 (i) 工作和等量的内部循环 (j) work 因此,每个线程完成的工作总量是相同的。因此,我们可以简单地坚持使用默认的静态调度来提供最佳负载平衡。
float A[100][100];
for(int i = 0; i < 100; i++)
{
for(int j = 0; j < 100; j++)
{
A[i][j] = 1.0f;
}
}
动态调度
当您知道每个线程不会通过使用静态调度来完成相同数量的工作时,就会使用动态调度。
然而,在下面的代码中,
float A[100][100];
for(int i = 0; i < 100; i++)
{
for(int j = 0; j < i; j++)
{
A[i][j] = 1.0f;
}
}
内循环变量j依赖于i。如果使用默认的静态调度,外循环 (i) 的工作可能会在 4 个线程之间平均分配,但内循环 (j) 的工作会很大一些线程。这意味着每个线程不会在静态调度中完成相同数量的工作。静态调度不会导致线程之间的最佳负载平衡。因此我们切换到动态调度(调度在运行时完成)。这样可以确保代码实现最佳负载平衡。
注意:你也可以指定chunk_size进行调度。这取决于循环大小。