OpenMP的遇到parallel指令后创建的线程team的数量由如下过程决定:
1. if子句的结果
2. num_threads的设置
3. omp_set_num_threads()库函数的设置
4. OMP_NUM_THREADS环境变量的设置
5. 编译器默认实现(一般而言,默认实现的是总线程数等于处理器的核心数)
(http://blog.csdn.net/gengshenghong/article/details/6956878查看更多信息)
2、3、4优先级依次降低的,也就是前面的设置可以覆盖后面的设置,当然也是相对而言,num_threads子句只会影响当前的并行区域,而omp_set_num_threads对OMP_NUM_THREADS环境变量的覆盖是在整个程序运行期间全局的。
(2)几个容易混淆的OpenMP函数
1. omp_get_thread_num
获取线程的num,即ID。这里的ID是OpenMP的team内的ID,在OpenMP中,一个team内的线程的ID是俺顺序排列的,0、1、2...
说明:此函数在并行区域外或者并行区域内都可以调用。在并行区域外,获取的是master线程的ID,即为0。在并行区域内,每次执行到此函数,获取的是当前执行线程的ID。
openmp并行程序在多核linux上最大化使用cpu的方法如下:
#include <stdio.h>#include <stdlib.h>
#include <omp.h>
#include <time.h>
int main()
{
long long i
long double sum = .0
long double sec = .0
// Multi-thread compute start
clock_t t1 = clock()
#pragma omp parallel for
for (i = 0 i < 1000000000 i++)
{
sum += i/100
}
clock_t t2 = clock()
sec = (t2 - t1)
//sec = (t2 - t1)
printf("Program costs %.2Lf clock tick.\n", sec)
exit(EXIT_SUCCESS)
}
以上代码中,#pragma omp parallel for
这一行的作用即是调用openmp的功能,根据检测到的CPU核心数目,将for (i = 0i <1000000000i++)这个循环执行过程平均分配给每一个CPU核心。
去掉#pragma omp parallel for这行,则和普通的串行代码效果一致。
注意,要使用openmp功能,在编译的时候需要加上-fopenmp编译参数。
以下是两种编译搭配两种代码出现的4种结果,可以很直观地看到效果:
1、代码里含有#pragma omp parallel for,编译参数有-fopenmp
Endys-MacBook-Pro:Desktop endy$ vi test.c
Endys-MacBook-Pro:Desktop endy$ gcc-6 test.c -o test -fopenmp
Endys-MacBook-Pro:Desktop endy$ ./test
Program costs 50202611.00 clock tick.
2、代码里含有#pragma omp parallel for,编译参数没有-fopenmp
Endys-MacBook-Pro:Desktop endy$ gcc-6 test.c -o test
Endys-MacBook-Pro:Desktop endy$ ./test
Program costs 4068178.00 clock tick.
3、代码里没有#pragma omp parallel for,编译参数有-fopenmp
Endys-MacBook-Pro:Desktop endy$ vi test.c
Endys-MacBook-Pro:Desktop endy$ gcc-6 test.c -o test -fopenmp
Endys-MacBook-Pro:Desktop endy$ ./test
Program costs 4090744.00 clock tick.
4、代码里没有#pragma omp parallel for,编译参数没有-fopenmp
Endys-MacBook-Pro:Desktop endy$ vi test.c
Endys-MacBook-Pro:Desktop endy$ gcc-6 test.c -o test
Endys-MacBook-Pro:Desktop endy$ ./test
Program costs 4170093.00 clock tick.
可以看出,只有在情况1下,openmp生效,其他3种情况下,均为单核运行,2、3、4结果较为接近,而1的运行结果大约相差25%。
值得注意的是,使用多核心的case 1竟然比单核的其他3种case慢了25%,原因是在这种单一的循环运算中,并行分配CPU任务的指令比直接执行下一个循环指令的效率更低。所以并不是用并行运算就一定能够提高运算效率的,要根据实际情况来判断。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)