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

news2024/9/24 15:23:39

本文主要介绍OpenMP并行编程技术,编程模型、指令和函数的介绍、以及OpenMP实战的几个例子。希望给OpenMP并行编程者提供指导。

🎬个人简介:一个全栈工程师的升级之路!
📋个人专栏:高性能(HPC)开发基础教程
🎀CSDN主页 发狂的小花
🌄人生秘诀:学习的本质就是极致重复!

目录

一、OpenMP 简介

二、OpenMP 编程模型

1. 指令与库函数

1.1 OpenMP指令格式

1.1.1 并行区域(Parallel Region)

1.1.2 并行构造(Parallel Construct)

1.1.3 任务(Task)

1.1.4 同步(Synchronize)

1.2 OpenMP常用的指令和函数

1.3 OpenMP常用库函数

2. 并行执行

3. 线程管理

4. 同步与通信

5. 调度策略

三、OpenMP编程实战

1 Linux下编译选项

2 C语言 OpenMP 并行化程序示例(包含)

3 C++ OpenMP并行编程示例(包含宏定义#ifdef _OPENMP)

4 OpenMP 多线程性能对比


一、OpenMP 简介

        OpenMP 是一个为共享内存并行计算设计的编程接口,广泛应用于 Fortran、C 和 C++ 语言。它提供了一套编译器指令和库函数,使得开发者能够轻松地编写并行程序。OpenMP 的“fork/join”模型是其中最核心的并行执行模式,其中最初只有一个主线程在运行。当遇到需要并行计算的部分时,主线程会派生出其他线程来执行并行任务。当并行代码执行完毕,派生的线程会退出或挂起,控制权回到主线程。类似与多线程技术。

二、OpenMP 编程模型

1. 指令与库函数

        OpenMP 的基本语法是通过预处理指令 #pragma omp 来实现的。例如,#pragma omp parallel for 用于并行化 for 循环。此外,OpenMP 还提供了一系列的库函数,用于线程的创建、同步等操作。这些库函数和指令使得开发者能够更灵活地控制并行程序的执行。

1.1 OpenMP指令格式

1.1.1 并行区域(Parallel Region)

        用于指定一个代码块,该代码块将在多个线程上并行执行。

#pragma omp parallel
{
    // 并行执行的代码块
}
1.1.2 并行构造(Parallel Construct)

        用于创建一个新线程并执行指定的代码块

#pragma omp parallel sections
{
    #pragma omp section
    {
        // 线程1执行的代码块
    }
    #pragma omp section
    {
        // 线程2执行的代码块
    }
}
1.1.3 任务(Task)

        用于创建一个新任务并在当前线程上执行指定的代码块。

#pragma omp task firstprivate(a, b) shared(c)
{
    // 任务执行的代码块,使用变量a和b,以及共享变量c
}
1.1.4 同步(Synchronize)

        用于等待所有线程完成指定的任务。

#pragma omp for schedule(static, chunk_size) reduction(+:sum)
for (int i = 0; i < n; i++) {
    // 循环体,使用变量i和sum
}

1.2 OpenMP常用的指令和函数

  1. parallel:用于指定一个代码段,该代码段将在多个线程上并行执行。

  2. for:用于for循环之前,将循环分配到多个线程中并行执行,必须保证每次循环之间无相关性。

  3. parallel for:parallel 和 for语句的结合,也是用在一个for循环之前,表示for循环的代码将被多个线程并行执行。

  4. sections:用在可能会被并行执行的代码段之前。

  5. parallel sections:parallel和sections两个语句的结合。

  6. critical:用在一段代码临界区之前。

  7. single:用在一段只被单个线程执行的代码段之前,表示后面的代码段将被单线程执行。

  8. flush:用来保证线程的内存临时视图和实际内存保持一致,即各个线程看到的共享变量是一致的。

  9. barrier:用于并行区内代码的线程同步,所有线程执行到barrier时要停止,直到所有线程都执行到barrier时才继续往下执行。

  10. atomic:用于指定一块内存区域被制动更新。

  11. master:用于指定一段代码块由主线程执行。

  12. ordered:用于指定并行区域的循环按顺序执行。

  13. threadprivate:用于指定一个变量是线程私有的。

  14. copyprivate:配合single指令,将指定线程的专有变量广播到并行域内其他线程的同名变量中;

  15. copyin n:用来指定一个threadprivate类型的变量需要用主线程同名变量进行初始化;

  16. default:用来指定并行域内的变量的使用方式,缺省是shared。

1.3 OpenMP常用库函数

        OpenMP库函数是一组用于并行计算的函数,它们可以帮助程序员在C、C++和Fortran等编程语言中实现多线程编程。以下是一些常用的OpenMP库函数:

  1. omp_get_num_threads():返回正在执行的线程数。
  2. omp_get_max_threads():返回支持的最大线程数。
  3. omp_get_thread_num():返回当前线程的编号。
  4. omp_get_num_procs():返回正在执行的程序的处理器数。
  5. omp_set_num_threads():设置并行区域中的线程数。
  6. omp_get_nested():测试当前块是否嵌套在其他并行区域内。
  7. omp_set_nested():设置当前块允许嵌套在其他并行区域内。
  8. omp_get_schedule():获取指定并行区域的调度策略。
  9. omp_set_schedule():设置指定并行区域的调度策略。
  10. omp_get_chunk_size():获取指定并行区域的块大小。
  11. omp_set_chunk_size():设置指定并行区域的块大小。
  12. omp_barrier():在所有线程都到达该点时阻塞所有线程。
  13. omp_critical():创建一个临界区,确保同一时间只有一个线程可以执行该段代码。
  14. omp_atomic():对一个变量进行原子操作,确保多个线程对该变量的操作是有序的。
  15. omp_flush():将缓冲区中的数据立即写入共享内存或设备。
  16. omp_lock_t:用于同步的锁类型。
  17. omp_init_lock():初始化锁对象。
  18. omp_destroy_lock():销毁锁对象。
  19. omp_set_lock():对锁对象加锁。
  20. omp_unset_lock():对锁对象解锁。

2. 并行执行

        OpenMP 提供了多种并行执行的方法,如 parallel for、parallel sections 等。这些方法使得开发者能够将代码块分配给多个线程执行,从而实现更高效的计算。通过合理地划分代码块和选择合适的并行执行方法,开发者可以显著提高程序的性能。

3. 线程管理

        OpenMP 提供了一些指令和函数,如 num_threads、thread_bind 等,用于设置和控制并行区域中的线程数量和绑定策略。这些功能使得开发者能够更好地控制并行程序的执行流程,确保程序的正确性和稳定性。

4. 同步与通信

        为了确保并行执行的正确性,OpenMP 提供了一些同步机制,如 barrier、critical、atomic 等。这些机制确保了线程之间的正确协作和数据一致性。此外,还提供了一些数据传输函数,如 reduction,用于实现线程之间的数据共享和计算结果的汇总。这些同步和通信机制是并行程序中必不可少的部分,它们确保了程序的正确性和可靠性。

5. 调度策略

        OpenMP 支持多种调度策略,如静态调度、动态调度和运行时调度。这些调度策略允许开发者根据需要选择合适的调度策略来优化程序的性能。通过合理地选择调度策略,开发者可以更好地平衡线程的负载和利用系统资源,从而提高程序的执行效率。

三、OpenMP编程实战

1 Linux下编译选项

        Linux下GCC编译器仅仅编译选项增加-fopenmp即可完成对OpenMP的支持。

2 C语言 OpenMP 并行化程序示例(包含<omp.h>)

#include <omp.h>

#include <stdio.h>


int main() {

    #pragma omp parallel for
    
    for (int i = 0; i < 10; i++) {

        printf("Thread %d: %d\n", omp_get_thread_num(), i);

    }

    return 0;

}

这个程序使用了 #pragma omp parallel for 指令将 for 循环进行并行化。在循环体内部,使用 omp_get_thread_num() 函数获取当前线程的编号,并打印出来。这个示例展示了 OpenMP 的基本用法和并行化效果,通过简单的修改和调整,你可以将其应用于更复杂的并行计算任务。

        运行结果:

        由于使用的电脑是八核的,因此,最多有八个线程,由上述的线程编号可以看出。

如果将上述的循环代码变成8个,如下:

#include <omp.h>

#include <stdio.h>


int main() {

    #pragma omp parallel for
    
    for (int i = 0; i < 8; i++) {

        printf("Thread %d: %d\n", omp_get_thread_num(), i);

    }

    return 0;

}

        运行结果:

        运行结果是八个线程,线程编号和循环编号相同。

3 C++ OpenMP并行编程示例(包含宏定义#ifdef _OPENMP)

#include <iostream>
#include <omp.h>
int main()
{
    #ifdef _OPENMP // 如果定义了这个宏
    std::cout << "Hello, OpenMP!" << std::endl;

    #pragma omp parallel for
    for (int i = 0;i < 8;i++)
    {
        printf("thread ID is %d i = %d\n",omp_get_thread_num(),i);
    }
    #else
    std::cout << "OpenMP is not enabled." << std::endl;
    #endif
    return 0;
}

        运行结果:

        C++ OpenMP并行编程例子。-fopenmp编译选项开启后,_OPENMP宏被打开。

4 OpenMP 多线程性能对比

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

void test()
{
    for (int i = 0; i < 80000; i++)
    {
        //执行代码
    }
}

int main(int argc, char **argv)

{
    #ifdef _OPENMP

    printf("OpenMP is Enable!\n");
    #else
     printf("OpenMP is Disable!\n");
    #endif

    float startTime = omp_get_wtime();
    //指定2个Thread
#pragma omp parallel for num_threads(2)
    for (int i = 0; i < 80000; i++)
    {
        test();
    }
    float endTime = omp_get_wtime();
    printf("2 个Thread,latency: %f\n", endTime - startTime);
    startTime = endTime;
    //指定4个Thread
#pragma omp parallel for num_threads(4)
    for (int i = 0; i < 80000; i++)
    {
        test();
    }
    endTime = omp_get_wtime();
    printf("4 个Thread,latency: %f\n", endTime - startTime);
    startTime = endTime;
    //指定8个Thread
#pragma omp parallel for num_threads(8)
    for (int i = 0; i < 80000; i++)
    {
        test();
    }
    endTime = omp_get_wtime();
    printf("8 个Thread,latency: %f\n", endTime - startTime);
    startTime = endTime;
    //指定12个Thread

#pragma omp parallel for num_threads(10)
    for (int i = 0; i < 80000; i++)
    {
        test();
    }
    endTime = omp_get_wtime();
    printf("10 个Thread,latency: %f\n", endTime - startTime);
    startTime = endTime;
    //不使用OpenMP
    for (int i = 0; i < 80000; i++)
    {
        test();
    }
    endTime = omp_get_wtime();
    printf("不使用OpenMP Mutil Thread,latency: %f\n", endTime - startTime);
    startTime = endTime;
    return 0;
}

        运行结果:

        分析结果可知,随着线程数量的增加运行的时间减少,由于使用的电脑是八核的,因此并行只能同时有八个线程,使用十个线程的运行效率不增反减。

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

下一节将继续开展OpenMP编程更加详细的实战。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1364848.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

实现多级缓存(Redis+Caffeine)

文章目录 多级缓存的概述多级缓存的优势 多级缓存的概述 在高性能的服务架构设计中&#xff0c;缓存是一个不可或缺的环节。在实际的项目中&#xff0c;我们通常会将一些热点数据存储到Redis或MemCache这类缓存中间件中&#xff0c;只有当缓存的访问没有命中时再查询数据库。在…

详解Java中的原子操作

第1章&#xff1a;什么是原子操作 大家好&#xff0c;我是小黑&#xff0c;面试中一个经常被提起的话题就是“原子操作”。那么&#xff0c;到底什么是原子操作呢&#xff1f;在编程里&#xff0c;当咱们谈论“原子操作”时&#xff0c;其实是指那些在执行过程中不会被线程调度…

thinkphp学习03-url访问模式

多应用&#xff1a;http://serverName/index.php/应用/控制器/操作/参数/值…&#xff1b;单应用&#xff1a;http://serverName/index.php/控制器/操作/参数/值…&#xff1b; http://localhost:8506/index.php Contoller下新建Test.php <?php namespace app\controlle…

电脑丢失dll文件怎么办,dll修复工具可一键修复dll问题

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中最常见的就是“找不到指定的模块”或“无法找到某某.dll文件”。这种情况通常是由于dll文件丢失或损坏导致的。那么&#xff0c;究竟是什么原因导致了dll文件的丢失呢&#xff1f;又该如何预防dll文件…

labelme的安装

首先尝试在(openmmlab)的python3.8的环境下安装&#xff08;失败&#xff09;。应该是我环境其他部分不对&#xff0c;和python版本应该没什么关系。&#xff08;后续&#xff0c;创建新的环境后成功&#xff0c;可直接看最后一部分。&#xff09; 首先安装是没问题的 pip in…

快手面经总结(2024最新)

快手 面经1-一面 开始先是手撕算法两道 自我介绍两道手撕 将字符串转化为整数 (这里当时出现溢出值问题&#xff0c;进行了思考解决&#xff0c;写了两种方式)synchronize &#xff0c; 可以使用的几种形式&#xff0c;代码写出 操作系统 和 数据结构 hash解决冲突 &#xff…

e2studio开发STHS34PF80人体存在传感器(1)----获取人体存在状态

e2studio开发STHS34PF80人体存在传感器.1--获取人体存在状态 概述视频教学样品申请完整代码下载主要特点硬件准备接口最小系统图新建工程工程模板保存工程路径芯片配置工程模板选择时钟设置UART配置UART属性配置设置e2studio堆栈e2studio的重定向printf设置R_SCI_UART_Open()函…

canal本地搭建以及运行

具体的文档可参考官网文档&#xff1a;https://github.com/alibaba/canal/wiki canal [kənl]&#xff0c;译意为水道/管道/沟渠&#xff0c;主要用途是基于 MySQL 数据库增量日志解析&#xff0c;提供增量数据订阅和消费 工作原理 canal 模拟 MySQL slave 的交互协议&#x…

解决Canvas画图清晰度问题

最近在开发Web端远程桌面的时候遇到的一个问题&#xff0c;解决记录一下&#xff0c;分享给各位有需要用到的朋友。 先吹下水&#xff1a;远程桌面的连接我们是通过Websocket连接后&#xff0c;后端不断返回远程端的界面二进制数据流&#xff0c;我接收到之后转为图像&#xf…

mxxWechatBot微信机器人自定义接口支持配置多个关键词、多个群聊和好友

大家伙&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。 前言 注意&#xff1a; 免责声明&#xff1a;该工具仅供学习使用&#xff0c;禁止使用该工具从事违法活动&#xff0c;否则永久拉黑​封禁账号。本工具我不会绝对保证对你的账号没有影响…

案例精选|淄博绿能燃气工程有限公司日志审计系统建设方案

淄博绿能燃气工程有限公司&#xff0c;成立于1994年&#xff0c;前身为淄博市煤气公司管道液化气分公司。公司业务主要涉及天然气、液化气等市政工程施工及城镇燃气供应等领域&#xff0c;具有市政公用工程施工总承包二级资质&#xff0c;《压力管道安装许可证》压力管道安装GB…

看图识熊(三)

使用Windows Machine Learning加载ONNX模型并推理 环境要求 Windows Machine Learning支持在Windows应用程序中加载并使用训练好的机器学习模型。Windows 10从10.0.17763.0版本开始提供这套推理引擎&#xff0c;所以需要安装17763版本的Windows 10 SDK进行开发&#xff0c;并…

实战Flink Java api消费kafka实时数据落盘HDFS

文章目录 1 需求分析2 实验过程2.1 启动服务程序2.2 启动kafka生产 3 Java API 开发3.1 依赖3.2 代码部分 4 实验验证STEP1STEP2STEP3 5 时间窗口 1 需求分析 在Java api中&#xff0c;使用flink本地模式&#xff0c;消费kafka主题&#xff0c;并直接将数据存入hdfs中。 flin…

秒懂百科,C++如此简单丨第十五天:指针

目录 必看信息 Everyday English 前言 &#x1f4dd;了解指针 &#x1f4dd;定义指针 &#x1f4dd;分析指针 &#x1f4dd;运用指针 总结 必看信息 ▶本篇文章由爱编程的小芒果原创&#xff0c;未经许可&#xff0c;严禁转载。 ▶本篇文章被收录于秒懂百科&#xff0c…

网络层协议及IP编址

0x00 前言 本节为网络层协议及IP编址内容 IP地址的范围&#xff1a;0.0.0.0-255.255.255.255 IP分为网络位以及主机位。子网划分就是向主机位借位。 网络层协议 IPICMP&#xff08;internet Control message protocol&#xff09;IPX IP协议的作用 为网络层的设备提供逻…

2023湾区产城创新大会:培育数字化供应链金融新时代

2023年12月26日&#xff0c;由南方报业传媒集团指导&#xff0c;南方报业传媒集团深圳分社主办的“新质新力——2023湾区产城创新大会”在深圳举行。大会聚集里国内产城研究领域的专家学者以及来自产业园区、金融机构、企业的代表&#xff0c;以新兴产业发展为议题&#xff0c;…

【计算机网络】网络基础--协议/网络协议/网络传输流程/地址管理

文章目录 一、计算机网络背景二、协议1.协议是什么2.为什么要有协议 三、网络协议1.为什么要进行协议分层2.OSI七层模型3.TCP/IP五层(或四层)模型 四、网络传输基本流程1.协议报头2.局域网3.数据包封装和分用4.网络传输流程图 五、网络中的地址管理1.认识IP地址2.认识MAC地址3.…

C++与数据库MySQL锁——模拟订票(事务)

假设订票的时候&#xff0c;好几个人同时进入&#xff0c;查看这张票是否售出&#xff0c;假如同时购买了这张票&#xff0c;那对于售票行业来说&#xff0c;可能就会发生低级错误。那么如何避免这类事情发生呢&#xff1f; 解决办法&#xff1a; 在一个人访问的时候&#xf…

DataFunSummit:2023年知识图谱在线峰会-核心PPT资料下载

一、峰会简介 AIGC&#xff0c;ChatGPT以及发布的GPT-4相信已经给大家带来足够的冲击&#xff0c;那么对于知识图谱的应用产生哪些变化和变革&#xff1f;知识图谱在其中如何发挥作用呢&#xff1f;通过LLM是否有可能辅助创建通用大规模知识图谱&#xff1f;AIGC时代下行业知识…

burpsuite专业版的安装和破解(2024年最新)

burpsuite专业版的安装和破解&#xff08;2024年最新&#xff09; 简介视频教程下载BP专业版第一步第二步&#xff1a;下载第三步第四步&#xff1a;打开powershell界面第五步&#xff1a;在powershell中执行BurpLoaderKeygen.jar文件第六步&#xff1a;破解第七步&#xff1a;…