2024年Go最全并行计算之OpenMP入门简介_openmp 并行计算(6),阿里Golang面试必问

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

#pragma omp parallel for


这个句子代表了C++中使用OpenMP的基本语法规则:\*\*#\*\***pragma omp** **指令** **[****子句****[****子句****]…]**


**1. OpenMP指令与库函数**


OpenMP包括以下**指令**:


* \*\*parallel:\*\*用在一个代码段之前,表示这段代码将被多个线程并行执行
* **for**:用于for循环之前,将循环分配到多个线程中并行执行,必须保证每次循环之间无相关性
* **parallel for**:parallel 和 for语句的结合,也是用在一个for循环之前,表示for循环的代码将被多个线程并行执行
* \*\*sections:\*\*用在可能会被并行执行的代码段之前
* \*\*parallel sections:\*\*parallel和sections两个语句的结合
* \*\*critical:\*\*用在一段代码临界区之前
* \*\*single:\*\*用在一段只被单个线程执行的代码段之前,表示后面的代码段将被单线程执行
* \*\*barrier:\*\*用于并行区内代码的线程同步,所有线程执行到barrier时要停止,直到所有线程都执行到barrier时才继续往下执行
* \*\*atomic:\*\*用于指定一块内存区域被制动更新
* \*\*master:\*\*用于指定一段代码块由主线程执行
* \*\*ordered:\*\*用于指定并行区域的循环按顺序执行
* \*\*threadprivate:\*\*用于指定一个变量是线程私有的


OpenMP除上述指令外,还有一些库函数,下面列出几个常用的**库函数**:


* **omp\_get\_num\_procs**:返回运行本线程的多处理机的处理器个数
* \*\*omp\_get\_num\_threads:\*\*返回当前并行区域中的活动线程个数
* \*\*omp\_get\_thread\_num:\*\*返回线程号
* \*\*omp\_set\_num\_threads:\*\*设置并行执行代码时的线程个数
* \*\*omp\_init\_lock:\*\*初始化一个简单锁
* \*\*omp\_set\_lock:\*\*上锁操作
* \*\*omp\_unset\_lock:\*\*解锁操作,要和omp\_set\_lock函数配对使用
* \*\*omp\_destroy\_lock:\*\*omp\_init\_lock函数的配对操作函数,关闭一个锁


OpenMP还包括以下**子句**:


* \*\*private:\*\*指定每个线程都有它自己的变量私有副本
* \*\*firstprivate:\*\*指定每个线程都有它自己的变量私有副本,并且变量要被继承主线程中的初值
* \*\*lastprivate:\*\*主要是用来指定将线程中的私有变量的值在并行处理结束后复制回主线程中的对应变量
* \*\*reduce:\*\*用来指定一个或多个变量是私有的,并且在并行处理结束后这些变量要执行指定的运算
* \*\*nowait:\*\*忽略指定中暗含的等待
* \*\*num\_threads:\*\*指定线程的个数
* \*\*schedule:\*\*指定如何调度for循环迭代
* \*\*shared:\*\*指定一个或多个变量为多个线程间的共享变量
* \*\*ordered:\*\*用来指定for循环的执行要按顺序执行
* \*\*copyprivate:\*\*用于single指令中的指定变量为多个线程的共享变量
* \*\*copyin:\*\*用来指定一个threadprivate的变量的值要用主线程的值进行初始化。
* \*\*default:\*\*用来指定并行处理区域内的变量的使用方式,缺省是shared


**2. parallel指令用法**


parallel 是用来构造一个并行块的,也可以使用其他指令如for、sections等和它配合使用。其用法如下:



#pragma omp parallel [for | sections] [子句[子句]…]
{
  // 需要并行执行的代码
}


例如,可以写一个简单的并行输出提示信息的代码:



#pragma omp parallel num_threads(8)
{
printf(“Hello, World!, ThreadId=%d\n”, omp_get_thread_num() );
}


在本机测试将会得到如下结果:


![img](https://img-blog.csdnimg.cn/img_convert/d0b493dc3f988f6a5015c54e1965f2b1.png)


结果表明,printf函数被创建了8个线程来执行,并且每一个线程执行的先后次序并不确定。和传统的创建线程函数比起来,OpenMP相当于为一个线程入口函数重复调用创建线程函数来创建线程并等待线程执行完。如果在上面的代码中去掉num\_threads(8)来指定线程数目,那么将根据实际CPU核心数目来创建线程数。


**3. for指令用法**


for指令则是用来将一个for循环分配到多个线程中执行。for指令一般可以和parallel指令合起来形成parallel for指令使用,也可以单独用在parallel语句的并行块中。其语法如下:



#pragma omp [parallel] for [子句]
for循环语句


例如有这样一个例子:



#pragma omp parallel for
for ( int j = 0; j < 4; j++ )
{
printf(“j = %d, ThreadId = %d\n”, j, omp_get_thread_num());
}


可以得到如下结果:


![img](https://img-blog.csdnimg.cn/img_convert/244eafa88ef2bd6a46434154d33d864f.png)


从结果可以看出,for循环的语句被分配到不同的线程中分开执行了。需要注意的是,如果不添加parallel关键字,那么四次循环将会在同一个线程里执行,结果将会是下面这样的:


![img](https://img-blog.csdnimg.cn/img_convert/363cc8254f0178b63947356fcc990183.png)


**4. sections和section的用法**


section语句是用在sections语句里用来将sections语句里的代码划分成几个不同的段,每段都并行执行。用法如下:



#pragma omp [parallel] sections [子句]
{
#pragma omp section
{
// 代码块
}
}


例如有这样一个例子:



#pragma omp parallel sections
{
#pragma omp section
printf(“section 1 ThreadId = %d\n”, omp_get_thread_num());
#pragma omp section
printf(“section 2 ThreadId = %d\n”, omp_get_thread_num());
#pragma omp section
printf(“section 3 ThreadId = %d\n”, omp_get_thread_num());
#pragma omp section
printf(“section 4 ThreadId = %d\n”, omp_get_thread_num());
}


可以得到如下结果:


![img](https://img-blog.csdnimg.cn/img_convert/f100b260dad215f7ff8b33ffb1e71d97.png)


结果表明,每一个section内部的代码都是(分配到不同的线程中)并行执行的。使用section语句时,需要注意的是这种方式需要保证各个section里的代码执行时间相差不大,否则某个section执行时间比其他section长太多就达不到并行执行的效果了。




![img](https://img-blog.csdnimg.cn/img_convert/51e31d60c0168a24643c1074d56edd88.png)
![img](https://img-blog.csdnimg.cn/img_convert/d5531a594df0886870f0baacd723064b.png)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618658159)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618658159)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值