OpenMP并行计算
创始人
2024-06-02 23:02:16
0

1. OpenMP简介

  • 通过多线程实现并行
  • 开放式的多处理框架 Open Multi-Process
  • 统一内存访问 : 多个CPU共享同一片内存,pthread/OpenMP在CPU上执行,属于统一内存访问
  • 非统一内存访问: 每个CPU有单独的Memory, 如MPI,通过总线通信的方式获取内存信息

OpenMP与PThread

  • pthread需要明确指定每个线程的行为,openmp只需简单的生命代码段需要并行即可
  • pthread依赖pthreads库,能被任意C编译器使用,openmp依赖openmp库,还依赖编译器支持某些特定操作
  • pthread可通过编写代码明确线程执行的过程,而openmp难以对底层的线程交互进行编程

Fork与Join

  • Fork: 由主线程创建出一系列并行化执行的子线程(派生)
  • Join: 多个线程完成工作之后,进行同步与终止,回到主线程执行(合并)

2. OpenMP使用

  • OpenMP提供基于指令的共享内存API
  • 编译器需要支持pragma指令提示的语句编译
  • 在系统中加入预处理指令一般是用来允许不符合C语言基本规划的行为

OpenMP parallel 指定并发线程数目

  • 编译器指令: #pragma omp parallel num_threads(num)
#include void test()
{int num = omp_get_thred_num();  // 获取线程是第几个int thrNum = omp_get_num_threads(); //获取线程总数// 打印当前线程是omp诸多线程中的哪一个
}int main()
{
#pragma omp parallel num_threads(4)test();
return 0;
}

OpenMP for

  • 编译器指令: #pragma omp parallel for
  • 指定指令后的for循环语句,将使用并行的方式执行,for语句需要满足:
    (1)循环的迭代器必须是可计算的,在循环前需要确定迭代的次数
    (2)循环代码块中不能包含break、return、exit
    (3)循环语句中不能使用goto跳出循环之外
    (4)迭代器只能被for语句中的增量表达式所修改
#pragma omp parallel for num_threads(4)for(int i = 0; i < 1000; ++i){if(i == 400){// 打印在哪个线程中执行}}
  • 数据依赖性: 循环中的计算依赖之前迭代计算的结果
    (1)编译器不检查被parallel for指令并行化的循环所包含的迭代间的依赖关系
    (2)一个或更多迭代的结果依赖其他迭代的循环,一般不能被正确的并行化
// 斐波那契数列案例

OpenMP Private Variables

  • OpenMP能共享进程中作用域范围内的变量,也可指定parallel块中能够访问该变量的线程集合
  • 能够被线程组中所有的线程访问的变量拥有共享作用域,而一个只能被单个线程访问的变量拥有私有作用域
  • Private在pragma指令中是一个可选附加的选项,它能直接高速编译器去将共享变量作为每个线程中的私有变量 #pragma omp … private()
  • Private的说明
    (1)每一个线程都是拥有独立的该变量的副本,不会共享原来的初始值
    (2)变量被定义为私有变量后,其他线程均不能访问某一个线程的私有变量
    (3)所有线程都不会使用先前变量的定义
    (4)所有线程均不能改变私有变量赋值
    (5)在循环的出入口均不会进行定义

*FirstPrivate的说明 #pragma omp parallel for firstprivate(var)
(1)告诉编译器私有变量在第一个循环会继承共享变量的值
(2)这个私有变量只会在每个线程的第一个循环继承原始的值,不会再每个循环中继承
(3)使用方法与Private一致

  • 变量的拷贝
    (1)变量是基础数据类型,如Int,double等,会将数据进行直接的拷贝
    (2)如果变量是一个数组,会分配数组大小的私有内存后,拷贝数组内容
    (3)如果变量是指针,会将地址指向的地址拷贝过去,指向相同的堆内容
    (4)如果变量是一个类的实例,会调用对应的构造函数构造一个私有的变量

  • LastPrivate的说明 #pragma omp parallel for lastprivate(var)
    (1)告诉编译器私有变量会在最后一个循环出去的时候,用私有变量的值替换掉共享变量的值

OpenMP Section

for: 在代码段中一部分代码再次分成多个子线程执行

single : 代码段中指定一部分代码仅由单个线程执行

master: 代码段中指定一部分代码仅由主线程执行

Section选项

  • sections在封闭代码的指定部分中,由线程组进行分配任务
  • 每个独立的section都需要在sections里面
  • 每个section都是被一个section执行
  • 不同的section可能执行不同的任务
  • 如果一个线程够快,它可能执行多个section

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...