马云谈2025的房价,新浪 博客可以做网站优化吗,自豪地采用wordpress,网页设计与制作课程标准中职本文主要介绍OpenMP并行编程的环境变量和实战、主要对比理解嵌套并行的效果。 #x1f3ac;个人简介#xff1a;一个全栈工程师的升级之路#xff01; #x1f4cb;个人专栏#xff1a;高性能#xff08;HPC#xff09;开发基础教程 #x1f380;CSDN主页 发狂的小花 个人简介一个全栈工程师的升级之路 个人专栏高性能HPC开发基础教程 CSDN主页 发狂的小花 人生秘诀学习的本质就是极致重复! 目录
一、OpenMP是什么
1 OpenMP的主要特点
2 Linux下OpenMP版本查看
3 OpenMP 环境变量
二、OPenMP实战
1 parallel
2 parallel for
3 最大线程数获取核数
4 嵌套的使用重点
4.1 简单单并行
4.2 双并行不允许嵌套
4.3 双并行允许嵌套 一、OpenMP是什么 OpenMPOpen Multi-Processing是一个用于C、C和Fortran编程语言的并行编程模型。 是由OpenMP Architecture Review Board牵头提出的并已被广泛接受的用于共享内存并行系统的多线程程序设计的一套指导性注释(Compiler Directive)。 支持OpenMP的编译器包括Sun CompilerGNU Compiler和Intel Compiler等。它提供了一套简单而强大的API使得开发人员可以轻松地在多核处理器上编写并行程序。 OpenMP通过将一个大的任务分解成多个小的任务并将这些任务分配给不同的线程来并行执行从而提高程序的性能。它提供了一些指令和函数用于控制线程的创建、同步和通信等操作。 OpenMP提供了一种高层的抽象描述用于并行算法。程序员可以通过在源代码中添加专用的pragma来明确表达他们的意图这样编译器就可以自动将程序进行并行化并在需要的地方添加同步、互斥和通信机制。当选择忽略这些pragma或者编译器不支持OpenMP时程序可以退化为普通的串行程序代码仍然可以正常运行只是无法利用多线程来加速程序执行。 作为高层抽象OpenMP并不适合需要复杂的线程间同步和互斥的场合。OpenMP的另一个缺点是不能在非共享内存系统(如计算机集群)上使用。在这样的系统上MPI使用较多。 OpenMP官网 OpenMP官网 OpenMP规范 OpenMP规范 1 OpenMP的主要特点 1. 简单易用OpenMP提供了一组简单的API使得开发人员可以轻松地编写并行代码。 2. 可移植性OpenMP可以在各种硬件平台上运行包括多核CPU、GPU和分布式系统等。 3. 高性能OpenMP可以利用多核处理器的并行计算能力提高程序的执行效率。 4. 共享内存模型OpenMP使用共享内存模型来实现线程之间的通信和同步避免了数据竞争的问题。 5. 支持多种编程范式OpenMP支持多种编程范式包括数据并行、任务并行和指令级并行等。
2 Linux下OpenMP版本查看 Linux的GCC编译器支持OpenMP版本的查看使用如下 echo |cpp -fopenmp -dM |grep -i open 执行后打印例如
#define _OPENMP 201511 可以到OpenMP Specification 查看对应的版本映射201511代表2015年11月发布的OpenMP版本。
3 OpenMP 环境变量 在性能优化-OpenMP基础教程一中主要介绍了OpenMP的指令和函数这里补充OpenMP的环境变量。
环境变量描述OMP_NUM_THREADS指定并行区域中使用的线程数OMP_PROC_BIND控制线程与处理器之间的绑定关系OMP_PLACES指定线程在处理器上的放置方式OMP_SCHEDULE控制循环迭代的调度策略OMP_STACKSIZE指定线程栈的大小OMP_DYNAMIC控制是否启用动态调度OMP_DEBUG控制是否启用OpenMP调试功能OMP_WAIT_POLICY控制线程等待其他线程完成的策略OMP_FLUSH_INTERVAL指定刷新内存缓存的时间间隔OMP_PROC_BIND控制线程与处理器之间的绑定关系OMP_PLACES指定线程在处理器上的放置方式OMP_SCHEDULE控制循环迭代的调度策略OMP_STACKSIZE指定线程栈的大小OMP_DYNAMIC控制是否启用动态调度OMP_DEBUG控制是否启用OpenMP调试功能OMP_WAIT_POLICY控制线程等待其他线程完成的策略OMP_FLUSH_INTERVAL指定刷新内存缓存的时间间隔
二、OPenMP实战 编译仅仅需要在g或者gcc 后面加编译选项 -fopenmp 。需要调用OpenMP的某些接口时需要在代码中包含omp.h头文件。例如
gcc test.c -fopenmp -o testg test1.cpp -fopenmp -o test1
1 parallel 编译制导指令parallel用来创建并行域后面紧跟需要创建并行域的代码紧跟的才有用可以使用{}括起来空行不算代码。
#includeiostream
#includeomp.h
using namespace std;
int main()
{#pragma omp parallel{cout parallel Test endl;}{cout serial Test endl;}return 0;
} 运行结果 由于笔者电脑有八个核所以打印8次。可以明显看出只有紧跟的代码才并行处理。OpenMP可以非常简单的编写并行程序这是它的优势。 注意输出也可能是乱码因为多线程共享标准输出引起的竞争条件。
2 parallel for paraller 仅仅只是让系统有了并行域创建了多个线程执行相同的内容并没有提高效率。使用parallel for可以让内容分配给不同的线程去执行注意是将一个任务划分为多个子任务让多核系统去执行这样就提高了效率这才是OpenMP的核心。parallel for 可以默认使用系统的多核线程数也可以用num_threads(number)指定线程数。 parallel for 只作用于紧跟的for循环但是这个for循环是可以嵌套的。 注意parallel for 需要搭配for 循环使用。
#includeiostream
#includeomp.h
using namespace std;
int main()
{#pragma omp parallel forfor (int i 0;i 8;i){printf(ThreadID: %d i %d 当前并行域线程数: %d \n,omp_get_thread_num(),i,omp_get_num_threads());}printf(****************************\n);#pragma omp parallel for num_threads(4)for (int i 0;i 8;i){printf(ThreadID: %d i %d 当前并行域线程数: %d \n,omp_get_thread_num(),i,omp_get_num_threads());}{cout serial Test endl;}return 0;
} 运行结果 3 最大线程数获取核数
#include iostream
#include omp.hint main()
{#ifdef _OPENMPprintf(Max threads nums: %d \n,omp_get_max_threads());#else#endifreturn 0;
} 运行结果 4 嵌套的使用重点 omp_set_nested(1) 设置允许嵌套使用作用域在下面所有代码不包括设置之前只有当设置为omp_set_nested(0)时嵌套允许才会被取消。 omp_get_nested() 测试当前并行域是否支持嵌套使用
4.1 简单单并行
#include stdio.h
#include omp.hint main()
{// omp_set_nested(1); // 设置允许嵌套并行可用 #pragma omp parallel num_threads(2){printf(第一级, thread %d of %d\n, omp_get_thread_num(),omp_get_num_threads());// #pragma omp parallel num_threads(2){printf(第二级, thread %d of %d\n, omp_get_thread_num(),omp_get_num_threads());}}return 0;
} 运行结果 分析可知2个线程都执行第一级和第二级两个线程都执行一次第一级和第二级。
4.2 双并行不允许嵌套
#include stdio.h
#include omp.hint main()
{// omp_set_nested(1); // 设置允许嵌套并行可用 #pragma omp parallel num_threads(2){printf(第一级, thread %d of %d\n, omp_get_thread_num(),omp_get_num_threads());#pragma omp parallel num_threads(2){printf(第二级, thread %d of %d\n, omp_get_thread_num(),omp_get_num_threads());}}return 0;
} 运行结果 分析可知第一级部分获得两个线程执行第二级一个线程执行两次这是不允许嵌套并行。
4.3 双并行允许嵌套
#include stdio.h
#include omp.hint main()
{omp_set_nested(1); // 设置允许嵌套并行可用 #pragma omp parallel num_threads(2){printf(第一级, thread %d of %d\n, omp_get_thread_num(),omp_get_num_threads());#pragma omp parallel num_threads(2){printf(第二级, thread %d of %d\n, omp_get_thread_num(),omp_get_num_threads());}}return 0;
} 运行结果 分析可知第一级在嵌套并行外部因此在允许嵌套并行的情况下执行两次第二级在嵌套并行内因此外部的每个线程会产生两个线程这样就有4个线程执行第二级这是允许嵌套执行的效果。 我的分享也就到此结束啦 如果我的分享也能对你有帮助那就太好了 若有不足还请大家多多指正我们一起学习交流 未来的富豪们点赞→收藏⭐→关注如果能评论下就太惊喜了 感谢大家的观看和支持最后☺祝愿大家每天有钱赚 下一节继续对OpenMP的更深层次的编程进行讲解