最近发现前辈程序里有使用openMP,不知道是干嘛用是,所以,稍微学习了一下。最浅显的理解就是openMP可以设置程序在多核里的“并行”执行。这里的“并行”是指程序里面的一块代码是并行,而不是所有程序的并行执行。或者说,只是对于for循环的并行执行。
使用openMP时有两个地方需要添加:
1.头文件要#include<omp.h>
2.在VS2013(我用的VS2013)工程属性中,设置支持“openMP”,如下图所示
openMP指令有很多,这里只介绍最简单的对for循环是并行处理。如下,
一、#pragma omp parallel for //默认是电脑核数,若是双核,则会启动2个线程,若是4核则会启动四个线程。
for (int i = 0; i < 10; i++)
{
//具体程序
}
二、也可以设置线程数
omp_set_num_threads(4);//设置四个线程,注意:并不是线程数越多越好,当设置的线程数超出CPU核数时,意味着CPU核需要进行线程间调度,而调度则需要时间,会影 响速度
#pragma omp parallel for
for (int i = 0; i < 10; i++)
{
//具体程序
}
三、openMP中的任务调度
问:为什么需要任务调度?
答:当for循环中每次迭代的计算量不相等时,如果简单地给各个线程分配相同次数的迭代的话,会造成各个线程计算负载不均衡,这会使得有些线程先执行完,有些后执行完,造成某些CPU空闲,影响程序性能。例如:100次循环,分给四个线程,每个线程25次循环。恰好,第一个线程的25次循环都是加法,而后面的都是加减乘除的混合运算,很明显第一个线程会很快执行完,造成CPU空闲。所以会出现线程间负载不均衡的问题,为解决这些问题OpenMP 中提供了几种对 for 循环并行化的任务调度方案。在 OpenMP 中,对 for 循环并行化的任务调度使用 schedule 子句来实现,
schedule 子句的使用格式为:
schedule(type[,size])
type 参数,表示调度类型,有四种调度类型如下:
· dynamic
· guided
· runtime
· static
这里只介绍dynamic:
for(i = 0; i < 10; i++ )
{
printf("i=%d, thread_id=%d\n", i, omp_get_thread_num());//omp_get_thread_num()会获得线程ID,即第几个线程
}
同样为四核CPU,i=0和i=1会给第一个线程,而i=2,i=3会给第二个线程,依次类推。