D. 使用 schedule 子句
并行区域在其中至少有一个障碍,在其末尾,并可以有不同的障碍。 在每个障碍,团队的其他成员必须等待最后一个线程到达。 若要使此等待时间,应为共享工作,以便所有线程同时到达关卡。 如果某些该共享工作在 为 构造中,可用于此目的 schedule 子句。
当存在重复对同一对象,选择 为 构造时间表可以主要取决于存储系统的特征,例如缓存的显示和大小,并且内存访问时间是否统一或非均匀的。 这些事项会始终会使其更可取使每个线程都引用同一个设置数组的元素在一系列循环的,因此,即使某些线程相对分配在特定的少工作循环。 这可以通过使用 静态 计划与所有循环的相同区域。 在下面的示例中,请注意零在第二个循环使用,下限,因此,即使 k 是更自然的,如果计划并不重要。
#pragma omp parallel
{
#pragma omp for schedule(static)
for(i=0; i<n; i++)
a[i] = work1(i);
#pragma omp for schedule(static)
for(i=0; i<n; i++)
if(i>=k) a[i] += work2(i);
}
余下的示例中,假定,内存存取不是主导注意事项,以及,除非另行说明,所有线程都接收可比较的计算资源。 在这些情况下,选择 为 构造计划取决于要执行在最近的前面的障碍和之间的提示的结束障碍或最新的后续障碍的所有共享工作,因此,如果有 nowait 子句。 对于每个类型的时间表,短的示例演示了如何安排类型可以是最佳选择。 简要讨论按照每个示例。
静态 计划为最简单的情况,包含唯一 为 构造,在每个迭代的并行区域还适用于要求相同工作负荷。
#pragma omp parallel for schedule(static)
for(i=0; i<n; i++) {
invariant_amount_of_work(i);
}
静态 计划后者以每个线程大致获取迭代的相同数量与其他线程的属性,并且,每个线程可以分别确定迭代指派给它。 因此不需要同步将工作,并且,,以为,每次迭代要求相同工作负荷,所有线程都应同时完成。
对于 p 线程团队,让 上限 (n/p) 是整数 q,满足 n = p*q - 具有 0 个 AMP_LT= r AMP_LT p. 的 r 。 静态 的实现用于此示例计划将 q 迭代到第一 p-1 线程和 q-r 迭代到最后一个线程。 另一个接受实现将 q 迭代到第一 PR 线程,因此, q-1 给剩余的 r 的 迭代线程。 这阐释程序为何不应依赖于特定的实现的详细信息。
动态 计划是适合于 为 结构化用例与要求更改迭代的,甚至不可预知的,工作负荷。
#pragma omp parallel for schedule(dynamic)
for(i=0; i<n; i++) {
unpredictable_amount_of_work(i);
}
动态 计划后者以线程比它采用另一个线程执行其最终迭代不等待关卡长时间运行的属性。 这需要迭代指派一个到线程,则会不断增多,与同步为每个分配。 同步开销可以指定正数值最小区块大小减少 k 大于 1,因此,线程次分配 k ,直到小于 k 保留。 这样可确保线程比它采用另一个线程执行 (最多) 长度不等待关卡 k 迭代其最终区块。
动态 计划非常有用,如果线程接收更改的计算资源,其效果和更改的工作量每个迭代的相同。 同样,动态调度可以通过也很有用,如果线程到达 为 构造更改的时间,在 引导 计划可能优于的一些情况。
引导 计划为线程可以达到更改的时间与要求大致相同的工作量的每个迭代的 为 结构化用例正确。 ,则可能发生,例如, 为 构造在一个或多个部分或 为 构造后使用 nowait 子句。
#pragma omp parallel
{
#pragma omp sections nowait
{
// ...
}
#pragma omp for schedule(guided)
for(i=0; i<n; i++) {
invariant_amount_of_work(i);
}
}
与 动态, 引导 计划确保线程比采用另一个线程执行其最终迭代长度不等待关卡,还是最终 k 迭代,如果 k 的 块范围指定。 在此类中计划, 引导 计划后者以属性所需少量同步。 对于块范围 k,一种典型的实现将 q = 上限 (n/p) 对第一个可用的线程迭代中,设置 n 到用 n-q 和 p*k,重复,直至所有迭代分配。
当最佳选择计划时不是尽可能明确地,也是为这些示例, 运行时 计划为体验不同计划和块范围很方便,而不必修改并重新编译程序。 也很有用,当最佳计划取决于 (用某种可预测的方式) 时程序为应用的输入数据。
若要查看权衡的示例在不同之间的计划,请考虑共享 1000 在迭代 8 个线程。 假定具有固定工作负荷在每个作为时间单位的迭代和使用的。
如果所有线程同时启动, 静态 在 125 个单位计划将导致构造执行,不同步。 但是,假设一个线程后期了 100 个单位在到达。 然后保持的七个线程等待 100 个单位在关卡,,整个构造的执行时间增加到 225。
由于 动态 和 引导 计划请确保线程不等待多个单元在关卡,延迟线程会导致延迟构造的执行时间只增加到 138 个单位,可以提高其从同步。 如果此延迟不是微不足道的,变为重要同步数只为 1000 动态 的,但 41 引导的,假定默认块之间的一个。 块范围为 25, 动态 和 引导 两个位于 150 个单位分别完成,以及从所需的同步的任何延迟,现在只计算 40 和 20,。