一起来学OpenMP(10)——线程的调度优化

一、引言

通过前边的介绍,知道了并行区域,默认情况下会自动生成与CPU个数相等的线程,然后并行执行并行区域中的代码,对于并行区域中的for循环,有特殊的声明方式,这样不同的线程可以分别运行for循环变量的不同部分。通过锁同步(atomic、critical、mutex函数)或事件同步(nowait、signal、section、master)来实现并行区域的同步控制。

具体的调度策略均由底层完成,本节介绍几种可以在上层对for循环进行控制的调度策略。

 

二、调度策略

调度策略     功能                                                                                                           适用情况

static         循环变量区域分为n等份,每个线程评分n份任务                                                 各个cpu的性能差别不大   

dynamic    循环变量区域分为n等份,某个线程执行完1份之后执行其他需要执行的那一份任务     cpu之间运行能力差异较大

guided      循环变量区域由大到小分为不等的n份,运行方法类似于dynamic                           由于任务份数比dynamic,所以可以减少调度开销

runtime     在运行时来适用上述三种调度策略中的一种,默认是使用static

 

三、示例

1. static

#include #include // OpenMP编程需要包含的头文件 int main() { #pragma omp parallel for schedule(static, 2) //static调度策略,for循环每两次迭代分成一个任务 for (int i = 0; i < 10; ++i) //被分成了5个任务,其中循环0~1,4~5,8~9分配给了第一个线程,其余的分配给了第二个线程 { std::cout << "Thread ID:" << omp_get_thread_num() << " Value:" << i << std::endl; } return 0; }

输出:

 

 

2. dynamic

代码:

#include #include // OpenMP编程需要包含的头文件 int main() { #pragma omp parallel for schedule(dynamic, 2) //dynamic调度策略,for循环每两次迭代分成一个任务 for (int i = 0; i < 10; ++i) //被分成了5个任务,只要有任务并且线程空闲,那么该线程会执行该任务 { std::cout << "Thread ID:" << omp_get_thread_num() << " Value:" << i << std::endl; } return 0; }

输出:

   

本次执行ID为1的线程分到了的循环变量任务为0~1,4~5,8~9。

再次执行如下:

 

本次执行ID为1的线程分到了任务2~3,6~7

 

3. guided

guided调度策略与dynamic区别在于,所分的任务块是从大到小排列的。具体分块算法为:每块的任务大小为:[迭代次数/线程个数的二倍]。其中每个任务的最小迭代次数由guided声明决定,默认是1。

举例说明:

#pragma omp for schedule[guided, 80]

for (int i = 0; i < 800; ++i){}

有两个cpu,那么任务分配如下:

第一个任务:[800/2*2] = 200

第二个任务:第一个任务分了200,还有600,那么[600/2*2] = 150

第三个任务:第二个任务分了150,还有450,那么[450/2*2] = 113

第四个任务:第三个任务分了113,还有337,那么[337/2*2] = 85

第五个任务:第四个任务分了85,还有252,那么[252/2*2] = 63,小于声明的80,那么这里为80

第六个任务:第五个任务分了80,还有172,根据声明,这里为80(因为会小于80)

第七个任务:第六个任务分了80,还有92,根据声明,这里为80(因为会小于80)

第八个任务:第七个任务分了80,还有12,根据声明,这里为12(因为不够80)

 

我在VS2008中没有看到guide的效果。

 

4. runtime

运行时底层动态选择调度策略。

 

四、小结

介绍了四种线程调度策略:static、dynamic、guided、runtime。

通过一些列的的介绍,大家若将所有的示例代码都跑一遍,应该可以掌握OpenMP的一些知识。

THE END

你可能感兴趣的:(多核编程)