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

相关内容

热门资讯

保存时出现了1个错误,导致这篇... 当保存文章时出现错误时,可以通过以下步骤解决问题:查看错误信息:查看错误提示信息可以帮助我们了解具体...
汇川伺服电机位置控制模式参数配... 1. 基本控制参数设置 1)设置位置控制模式   2)绝对值位置线性模...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
表格中数据未显示 当表格中的数据未显示时,可能是由于以下几个原因导致的:HTML代码问题:检查表格的HTML代码是否正...
本地主机上的图像未显示 问题描述:在本地主机上显示图像时,图像未能正常显示。解决方法:以下是一些可能的解决方法,具体取决于问...
不一致的条件格式 要解决不一致的条件格式问题,可以按照以下步骤进行:确定条件格式的规则:首先,需要明确条件格式的规则是...
表格列调整大小出现问题 问题描述:表格列调整大小出现问题,无法正常调整列宽。解决方法:检查表格的布局方式是否正确。确保表格使...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...