性能优化-OpenMP基础教程(三)

这篇具有很好参考价值的文章主要介绍了性能优化-OpenMP基础教程(三)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文主要介绍OpenMP并行编程的环境变量和实战、主要对比理解嵌套并行的效果。

🎬个人简介:一个全栈工程师的升级之路!
📋个人专栏:高性能(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是什么?

        OpenMP(Open Multi-Processing)是一个用于C、C++和Fortran编程语言的并行编程模型。

        是由OpenMP Architecture Review Board牵头提出的,并已被广泛接受的,用于共享内存并行系统的多线程程序设计的一套指导性注释(Compiler Directive)。

        支持OpenMP的编译器包括Sun Compiler,GNU 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 test

g++ test1.cpp -fopenmp -o test1

1 parallel

        编译制导指令parallel,用来创建并行域,后面紧跟需要创建并行域的代码,紧跟的才有用,可以使用{}括起来,空行不算代码。

#include<iostream>
#include"omp.h"
using namespace std;
int main()
{
    #pragma omp parallel
    {
        cout << "parallel Test" << endl;
    }
    {
        cout << "serial Test" << endl;
    }
    
 return 0;
}

        运行结果:

性能优化-OpenMP基础教程(三),高性能(HPC)开发基础教程,# OpenMP入门教程,linux,OpenMP,并行编程,嵌套并行,c++

        由于笔者电脑有八个核,所以打印8次。可以明显看出只有紧跟的代码才并行处理。OpenMP可以非常简单的编写并行程序,这是它的优势。

        注意:输出也可能是乱码,因为多线程共享标准输出引起的竞争条件

2 parallel for 

        paraller 仅仅只是让系统有了并行域,创建了多个线程执行相同的内容,并没有提高效率。使用parallel for可以让内容分配给不同的线程去执行,注意是将一个任务划分为多个子任务让多核系统去执行,这样就提高了效率,这才是OpenMP的核心。parallel for 可以默认使用系统的多核线程数,也可以用num_threads(number)指定线程数。

        parallel for 只作用于紧跟的for循环,但是这个for循环是可以嵌套的。

        注意parallel for 需要搭配for 循环使用。

#include<iostream>
#include"omp.h"
using namespace std;
int main()
{
    #pragma omp parallel for
    for (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;
}

        运行结果:

性能优化-OpenMP基础教程(三),高性能(HPC)开发基础教程,# OpenMP入门教程,linux,OpenMP,并行编程,嵌套并行,c++

3 最大线程数获取(核数)

#include <iostream>
#include <omp.h>

int main()
{
    
    #ifdef _OPENMP
        printf("Max threads nums: %d \n",omp_get_max_threads());
    #else

    #endif

    return 0;
}

        运行结果:

性能优化-OpenMP基础教程(三),高性能(HPC)开发基础教程,# OpenMP入门教程,linux,OpenMP,并行编程,嵌套并行,c++

4 嵌套的使用(重点)

        omp_set_nested(1) 设置允许嵌套使用,作用域在下面所有代码,不包括设置之前,只有当设置为omp_set_nested(0)时,嵌套允许才会被取消。

        omp_get_nested() 测试当前并行域是否支持嵌套使用

4.1 简单单并行

#include <stdio.h>
#include <omp.h>

int  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;
}

        运行结果:

性能优化-OpenMP基础教程(三),高性能(HPC)开发基础教程,# OpenMP入门教程,linux,OpenMP,并行编程,嵌套并行,c++

        分析可知2个线程,都执行第一级和第二级,两个线程都执行一次第一级和第二级。

4.2 双并行不允许嵌套

#include <stdio.h>
#include <omp.h>

int  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;
}

        运行结果:

性能优化-OpenMP基础教程(三),高性能(HPC)开发基础教程,# OpenMP入门教程,linux,OpenMP,并行编程,嵌套并行,c++

        分析可知,第一级部分获得两个线程执行,第二级一个线程执行两次,这是不允许嵌套并行。

4.3 双并行允许嵌套

#include <stdio.h>
#include <omp.h>

int  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;
}

        运行结果:

性能优化-OpenMP基础教程(三),高性能(HPC)开发基础教程,# OpenMP入门教程,linux,OpenMP,并行编程,嵌套并行,c++     

        分析可知,第一级在嵌套并行外部,因此在允许嵌套并行的情况下,执行两次;第二级在嵌套并行内,因此外部的每个线程会产生两个线程,这样就有4个线程执行第二级,这是允许嵌套执行的效果。

🌈我的分享也就到此结束啦🌈
如果我的分享也能对你有帮助,那就太好了!
若有不足,还请大家多多指正,我们一起学习交流!
📢未来的富豪们:点赞👍→收藏⭐→关注🔍,如果能评论下就太惊喜了
感谢大家的观看和支持!最后,☺祝愿大家每天有钱赚!!!

下一节继续对OpenMP的更深层次的编程进行讲解!文章来源地址https://www.toymoban.com/news/detail-777920.html

到了这里,关于性能优化-OpenMP基础教程(三)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 性能优化-OpenMP基础教程(三)

    本文主要介绍OpenMP并行编程的环境变量和实战、主要对比理解嵌套并行的效果。 🎬个人简介:一个全栈工程师的升级之路! 📋个人专栏:高性能(HPC)开发基础教程 🎀CSDN主页 发狂的小花 🌄人生秘诀:学习的本质就是极致重复! 目录 一、OpenMP是什么? 1 OpenMP的主要特点

    2024年02月03日
    浏览(37)
  • 性能优化-OpenMP基础教程(一)

    本文主要介绍OpenMP并行编程技术,编程模型、指令和函数的介绍、以及OpenMP实战的几个例子。希望给OpenMP并行编程者提供指导。 🎬个人简介:一个全栈工程师的升级之路! 📋个人专栏:高性能(HPC)开发基础教程 🎀CSDN主页 发狂的小花 🌄人生秘诀:学习的本质就是极致

    2024年02月03日
    浏览(47)
  • 《高性能MYSQL》-- 查询性能优化

    查询性能优化 深刻地理解MySQL如何真正地执行查询,并明白高效和低效的原因何在 查询的生命周期(不完整):从客户端到服务器,然后服务器上进行语法解析,生成执行计划,执行,并给客户端返回结果。 一条查询,如果查询得很慢,原因大概率是访问的数据太多 对于低

    2024年03月11日
    浏览(71)
  • 《高性能MySQL》——查询性能优化(笔记)

    将查询看作一个任务,那么它由一系列子任务组成,实际我们所做的就是: 消除一些子任务 减少子任务的执行次数 让子任务运行更快 查询的生命周期大概可分为 = { 客户端 服务器 : 进行解析 , 生成执行计划 执行:包括到存储引擎的调用,以及用后的数据处理 { 排序 分组

    2024年02月13日
    浏览(52)
  • 高性能MySQL实战(三):性能优化

    大家好,我是 方圆 。这篇主要介绍对慢 SQL 优化的一些手段,而在讲解具体的优化措施之前,我想先对 EXPLAIN 进行介绍,它是我们在分析查询时必要的操作,理解了它输出结果的内容更有利于我们优化 SQL。为了方便大家的阅读,在下文中规定类似 key1 的表示二级索引,key_

    2024年02月11日
    浏览(66)
  • C++高性能优化编程之如何测量性能(一)

    C++高性能优化编程系列 深入理解设计原则系列 深入理解设计模式系列 高级C++并发线程编程 不好的编程习惯,不重视程序性能测量分析让代码跑的更快,会导致 浪费大量的CPU周期、程序响应时间慢以及卡顿,用户满意度下降,进而浪费大量的时间返工去重构本应该一开始就

    2024年02月06日
    浏览(63)
  • MySQL高性能优化规范建议

    数据库命令规范 数据库基本设计规范 1. 所有表必须使用 Innodb 存储引擎 2. 数据库和表的字符集统一使用 UTF8 3. 所有表和字段都需要添加注释 4. 尽量控制单表数据量的大小,建议控制在 500 万以内。 5. 谨慎使用 MySQL 分区表 6.尽量做到冷热数据分离,减小表的宽度 7. 禁止在表中建

    2024年02月12日
    浏览(48)
  • 如何评估和优化系统的高性能

    系统的关键性能指标:吞吐量,延迟和TP。 吞吐量:反应单位时间内处理请求的能力。 延迟:从客户端发送请求到接收响应的时间。 延迟和吞吐量的曲线如下图所示: 总体来看,随着压力增大,系统单位时间内被访问的次数增加。结合延迟和吞吐量观察的话,系统优化性能

    2024年02月22日
    浏览(55)
  • Kafka高性能集群部署与优化

    Kafka 是由Apache Software Foundation开发的一个分布式流处理平台,源代码以Scala编写。Kafka最初是由LinkedIn公司开发的,于2011年成为Apache的顶级项目之一。它是一种高吞吐量、可扩展的发布订阅消息系统,具有以下特点: 高吞吐量:Kafka每秒可以处理数百万条消息。 持久化:数据存

    2024年02月13日
    浏览(59)
  • 数据库——MySQL高性能优化规范

    所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用 MySQL 保留(如果表名中包含查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名识意,并且最后不要超过 32 个字符 临时库表必须以 tmp_为前缀并以日期为后缀,

    2024年02月11日
    浏览(99)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包