[转]OpenMP中几个容易混淆的函数(线程数量/线程ID/线程最大数)以及并行区域线程数量的确定
说明:这部分内容比较基础,主要是分析几个容易混淆的OpenMP函数,加以理解。
(1)并行区域数量的确定:
在这里,先回顾一下OpenMP的parallel并行区域线程数量的确定,对于一个并行区域,有一个team的线程去执行,那么该分配多少个线程去执行呢?
OpenMP的遇到parallel指令后创建的线程team的数量由如下过程决定:
1. if子句的结果
2. num_threads的设置
3. omp_set_num_threads()库函数的设置
4. OMP_NUM_THREADS环境变量的设置
5. 编译器默认实现(一般而言,默认实现的是总线程数等于处理器的核心数)
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。
此函数比较容易理解,主要是不要和下面的omp_get_num_threads记混淆了。
2. omp_get_num_threads/omp_set_num_threads
设置/获取线程数量,此set函数是上面确定遇到parallel指令后创建team的线程的决定方式之一,用于覆盖OMP_NUM_THREADS环境变量的设置。
说明:尽管从函数名上看,它们是一对set/get函数,但是要区分它们的含义,set之后马上get,其值不一定等于set的结果,而且大部分情况都是不相等的!
首先来理解omp_set_num_threads():
作用上来说,我们知道它是用于覆盖环境变量OMP_NUM_THREDS的设置的,使用上来说,要注意的是,omp_set_num_threads只能用于并行区域之外,如果用于并行区域之内,在Debug下运行时会输出“User Error 1001: omp_set_num_threads should only be called in serial regions”到控制台,如果是Release模式不会输出,理论上应该是被忽略了。总之,在串行代码区调用omp_set_num_threads来设置线程数量。
然后分析omp_get_num_threads():
用于获取当前线程组(team)的线程数量,如果不在并行区调用,返回1.
这句话就清楚了描述了get的作用了,获取的是当前线程组的线程数量,所以一般会在并行区域调用,其返回的是实际的parallel区域内由上面几大因素决定之后的实际的运行的线程数量,并不是set的值,所以也很容易理解,在串行区调用它会返回1(所以一般也不会在串行区去调用)。
总结:omp_set_num_threads在串行区域调用才会有效,omp_get_num_threads获取当前线程组的线程数量,一般在并行区域调用,在串行区域调用返回为1。两个函数没有本质上的数量关系!
3. omp_get_max_threads:
从函数名看,貌似是“获取最大的线程数量”,是的,那么这个“最大的线程数量"的具体含义呢?下面是OpenMP文档上的一段话:
The omp_get_max_threads routine returns an upper bound on the number of threads that could be used to form a new team if a parallel region without a num_threads clause were encountered after execution returns from this routine。
很清楚的说明了,这个”最大数量“是指在不使用num_threads的情况下,OpenMP形成一个新的team能创建的最大线程数量。从这里要理解到:这个最大数量,是能确定的,与其在并行区域调用,还是在串行区域调用是无关的,因为它是返回OpenMP当前环境下去创建一个”新的“team能创建的可能的最大数量。简单的理解,其实,这个值就是由以下三者确定:omp_set_num_threads、OMP_NUM_THREADS、编译器默认实现。
注意:omp_get_max_threads可以在串行或并行区域内调用,而且其结果是一样的(在其间不调用omp_set_num_threads的情况下),如果有效调用(串行区调用)了omp_set_num_threads,会改变接下来调用omp_get_max_threads的值。另外,omp_get_max_threads的返回值可能会小于omp_set_num_threads。
4. 实例:
下面的例子是使用上面几个函数的例子,根据结果可以分析出上面提到的一些内容:
#include <omp.h> int main(int argc, _TCHAR* argv[])
{
printf("ID: %d, Max threads: %d, Num threads: %d \n",omp_get_thread_num(), omp_get_max_threads(), omp_get_num_threads());
omp_set_num_threads(5);
printf("ID: %d, Max threads: %d, Num threads: %d \n",omp_get_thread_num(), omp_get_max_threads(), omp_get_num_threads()); #pragma omp parallel num_threads(5)
{
// omp_set_num_threads(6); // Do not call it in parallel region
printf("ID: %d, Max threads: %d, Num threads: %d \n",omp_get_thread_num(), omp_get_max_threads(), omp_get_num_threads());
} printf("ID: %d, Max threads: %d, Num threads: %d \n",omp_get_thread_num(), omp_get_max_threads(), omp_get_num_threads()); omp_set_num_threads(6);
printf("ID: %d, Max threads: %d, Num threads: %d \n",omp_get_thread_num(), omp_get_max_threads(), omp_get_num_threads()); return 0;
}
[转]OpenMP中几个容易混淆的函数(线程数量/线程ID/线程最大数)以及并行区域线程数量的确定的更多相关文章
- 在不开启事件循环的线程中使用QTimer(QThread::run函数自带事件循环,在构造函数里创建线程,是一种很有意思的线程用法) good
引入 QTimer是Qt自带的定时器类,QTimer运行时是依赖于事件循环的,简单来说,在一个不开启事件循环(未调用exec() )的线程中,QTimer是无法使用的.通过分析Qt源码可发现,调用QT ...
- [转]OpenMP中的private/firstprivate/lastprivate/threadprivate之间的比较
转自:http://blog.csdn.net/gengshenghong/article/details/6985431 private/firstprivate/lastprivate/threa ...
- 并行计算之OpenMP中的任务调度
本文参考<OpenMP中的任务调度>博文,主要讲的是OpenMP中的schedule子句用法. 一.应用需求 在OpenMP并行计算中,任务调度主要用于并行的for循环.当for循环中每次 ...
- php中一些容易混淆的函数总结
在我们日常PHP开发中,经常会使用一些函数完成相关操作,但是有些函数功能相近,很容易混淆,再次总结一下 1. __DIR__ && getcwd() 看官方解释: getcwd: ...
- OpenMP 中的线程任务调度
OpenMP中任务调度主要针对并行的for循环,当循环中每次迭代的计算量不相等时,如果简单地给各个线程分配相同次数的迭代,则可能会造成各个线程计算负载的不平衡,影响程序的整体性能. 如下面的代码中,如 ...
- OpenMP中的同步和互斥
在多线程编程中必须考虑到不同的线程对同一个变量进行读写访问引起的数据竞争问题.如果线程间没有互斥机制,则不同线程对同一变量的访问顺序是不确定的,有可能导致错误的执行结果. OpenMP中有两种不同类型 ...
- js中几个容易混淆的概念
1. var name = "The Window";var object = {name : "My Object",getName: function(){ ...
- MATLAB中白噪声的WGN和AWGN函数的使用
MATLAB中白噪声的WGN和AWGN函数的使用如下: MATLAB中产生高斯白噪声非常方便,可以直接应用两个函数,一个是WGN,另一个是AWGN.WGN用于产生高斯白噪声,AWGN则用于在某一 信号 ...
- WinForm中新开一个线程操作 窗体上的控件(跨线程操作控件)
最近在做一个winform的小软件(抢票的...).登录窗体要从远程web页面获取一些数据,为了不阻塞登录窗体的显示,开了一个线程去加载数据远程的数据,会报一个错误"线程间操作无效: 从不是 ...
随机推荐
- 湖北校园网PC端拨号算法逆向
湖北校园网PC端拨号算法逆向 前言 上一文 PPPoE中间人拦截以及校园网突破漫谈我们谈到使用 PPPoE 拦截来获取真实的账号密码. 在这个的基础上,我对我们湖北的客户端进行了逆向,得到了拨号加密算 ...
- Mock常用占位符一览
1.随机字符串(类型 , 位数)@string(lower,10) lower : 小写字母upper : 大写字母number : 数字 2.随机int(下限 , 上限)@integer(60, 1 ...
- Spring Cloud 基于Consul 实现配置服务
Spring Cloud体系中提供了Config组件来进行配置服务管理.而Consul除了提供服务注册与发现功能外,同时也提供配置管理功能.本位将介绍如何结合Spring Cloud + Consul ...
- js图片向下流动
<div id=demo style=overflow:hidden;height:;width:;background:#f4f4f4;color:#ffffff><div id= ...
- 在论坛中出现的比较难的sql问题:22(触发器专题3)
原文:在论坛中出现的比较难的sql问题:22(触发器专题3) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. 所以,觉得有必要记录下 ...
- GRIT VIEW删除事件
1.点选表格后找到事件 RowCommand 2.輸入gvGroupUser_RowCommand后双击 ------注分 ...
- iOS - OC 使用运行时来获取并修改类
前言: Objective C的runtime技术功能非常强大,能够在运行时获取并修改类的各种信息,包括获取方法列表.属性列表.变量列表,修改方法.属性,增加方法,属性等等,本文对相 ...
- 【转】Java最常见的200+面试题
今天看到一份面试题总结,感觉很到位,主要包括以下模块:Java基础.容器.多线程.反射.对象拷贝.Java Web模块,异常.网络.设计模式.Spring/Spring MVC .Spring Boo ...
- WebService 的发布和调用
WebService 四种发布方式总结 :https://blog.csdn.net/zl834205311/article/details/51612207 调用webService的几种方式 ht ...
- C#-FileHelper
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...