0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

OpenMP优化相关知识

openEuler 来源:openEuler 作者:openEuler 2022-12-06 10:25 次阅读

作者介绍

谢依晖

湖南大学硕士研究生在读,

本科毕业于湖南大学计算机科学与技术专业

本文调研了4篇与OpenMP优化相关的文献,对优化点分析如下:

面向Open64的OpenMP程序优化[1]

跨越过程边界的并行区重构

Open64有着过程间分析优化部件,因此可以知道哪些函数使用了被调函数,从而可以通过在使用被调函数处放置合适的编译指导语句来完成并行区重构。

这样做的好处是:

进一步扩大并行块的大小;

将并行块提升到调用函数中,便于进一步对调用函数中的并行块合并。

以下给出例子:

programmain
callsub_procedure
end

subroutinesub_procedure
!$ompparallel
P
!$ompendparallel
end

优化后:

programmain
!$ompparallel
callsub_procedure
!$ompendparallel
end

subroutinesub_procedure
P
end

OpenMP并行编程模型与性能优化方法的研究及应用[2]

Cache命中率优化

数组合并:定义两个数组val[N]和key[N],在顺序访问val[i]和key[i]时可能会导致Cache冲突失效,若改为struct merge{key, val}就可以通过提高空间局部性减少Cache失效次数。

循环交换:C按行存储而Fortran按列存储,应根据存储的顺序来访问。

提取关键数据:提取关键数据可以减少重复存取的数据,例如在排序中用关键字和指针代替整个记录排序,这样就能让Cache无需存放无关数据而提高命中率。

分块:对于极大大小的数组,要在Cache中一次容纳整个数组是有困难的,但可以将数组分为多块,可有效降低Cache失效率。

循环调度优化

在OpenMP中可对并行循环指定调度方案,以将每个迭代分配给多个工作线程执行。其一般形式如下:

#pragmaompforschedule(schedule_name,chunk_size)
for(i=0;i< N; i++)

OpenMP编译与优化技术研究[3]

论文中给出了一种使用启发式规则来估计各种额外开销和调度参数的关系,得到一个线性不等式组,可以通过求解该不等式组得到较优的调度参数。

变量属性的优化

在OpenMP语句中每一次对变量的声明都对应一次新的地址分配。给出以下例子:

#pragmaompparallel
{
#pragmaompforprivate(a)
{...}
#pragmaompforprivate(a)
{...}
}

在如上代码中,编译器会为每个循环分配一个单独的私有变量,而优化后的代码如下所示:

#pragmaompparallelprivate(a)
{
#pragmaompfor
{...}
#pragmaompfor
{...}
}

How to Get Good Performance by Using OpenMP[4]

去除依赖

对于某些循环语句,存在依赖而导致无法使用OpenMP优化,但是这其中的某些依赖可以通过修改代码去除依赖而使用OpenMP运行代码。

下列循环存在反依赖:

for(inti=0;i< n; i++) {
  x = (b[i] + c[i]) / 2;
  a[i] = a[i + 1] + x;
}

除去循环之间的依赖后:

#pragmaompparallelforshared(a,a_copy)
for(inti=0;i< n; i++) {
  a_copy[i] = a[i + 1];
}
#pragma omp parallel for shared(a, a_copy) private(x)
for(int i = 0; i < n; i++) {
  x = (b[i] + c[i]) / 2;
  a[i] = a_copy[i] + x;
}

下列循环存在流依赖:

for(inti=1;i< n; i++) {
  b[i] = b[i] + a[i - 1];
  a[i] = a[i] + c[i];
}

在loop skewing之后:

b[1]=b[1]+a[0]
#pragmaompparallelforshared(a,b,c)
for(inti=1;i< n - 1; i++) {
  a[i] = a[i] + c[i];
  b[i + 1] = b[i + 1] + a[i];
}
a[n - 1] = a[n - 1] + c[n - 1];

负载不均衡

下段代码使用流水线形式处理,以块的形式读取数据,然后处理每个块并在下一个块之前将结果写入磁盘,造成极差的负载均衡。

for(i=0;i< N; i++) {
  readfromfile(i, ...);
  for(int j = 0; j < processingnum; j++) {
    processdata(); //lots of work
  }
  writetofile(i);
}

接下来这段代码使用动态调度来重叠I/O和处理数据,将上述流水线代码并行化。

#pragmaompparallel
{
/*preloaddatatobeusedinfirstiterationofthei-loop*/
#pragmaompsingle
{ReadFromFile(O,...);}
for(i=0;i

解决伪共享问题

inta[Nthreads][cache_line_size];
#pragmaompparallelforshared(Nthreads,a)schedule(static,1)
for(inti=0;i< Nthreads; i++)
 a[i] += i;

一般情况下,int型变量占四个字节,A[0]和A[1]的地址只差四个字节,小于一个Cache行,它们有着极大的可能在同一Cache行内,从而导致同时更新不同处理器的相同Cache行中的单个元素会导致整个Cache行无效。

对于False sharing问题,一般可以通过填充数组来优化。

inta[Nthreads][cache_line_size];
#pragmaompparallelforshared(Nthreads,a)schedule(static,1)
for(inti=0;i< Nthreads; i++)
 a[i][0] += i;

我们还对文献中的部分优化使用LLVM Flang编译器和classic-flang编译器进行了测试,测试结果请参考https://gitee.com/src-openeuler/flang/pulls/22/files。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 优化
    +关注

    关注

    0

    文章

    220

    浏览量

    23861
  • 函数
    +关注

    关注

    3

    文章

    4299

    浏览量

    62352
  • OpenMP
    +关注

    关注

    0

    文章

    12

    浏览量

    5604

原文标题:OpenMP优化调研系列文章(3)

文章出处:【微信号:openEulercommunity,微信公众号:openEuler】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    关于一些对OpenMP优化的方式

    本文调研了一些对OpenMP优化的方式。
    发表于 11-22 09:36 1088次阅读

    openMP的helloword的demo出错

    按照官方资料http://processors.wiki.ti.com/index.php/OpenMP_on_C6000#Installation,搭建了第一个案例,自己选择的目标配置
    发表于 06-21 00:52

    关于6678 openmp的几个问题

    大家好, 最近在学习6678上的omp库,遇到几个疑问,如下 1. 我注意到,带openmp的程序代码段都是放在msmc里的,当多个核都进入到并行域时,都是在msmc的同一个地址执行代码的,我想问1
    发表于 06-21 11:21

    C6678 openMP 例程 连接出错

    用的芯片是c6678,开发板是TMDSEVM6678L,开发环境ccs5.2。mcsdk2.1.2.5。openMP1.1.3.02 跑的是biosMulticore sdk 中的openMP例程
    发表于 06-21 00:52

    linux下的openmp编程基础知识介绍

    OpenMP是专门针对共享地址空间的平行计算机提供的并行计算库,在Intel C++和Visual C++ 8.0里通过#pragma支持。用OpenMP,可以不必去写诸如CreateThread
    发表于 07-22 06:45

    openmp相关资料下载

    嵌入式算法移植优化学习笔记1——openmp参考:1、https://www.oschina.net/p/openmp?hmsr=aladdin1e11、openmp简介
    发表于 12-14 09:03

    请问JPEG编码如何并行优化

    使用QT对Jpeg编码与解码功能进行优化,可以使用openmp,neon等各种方法
    发表于 05-16 21:25

    OpenMP优化调研系列文章(1)

    Abstract本文调研了一些对OpenMP进行优化的方法:H. Ma, R. Zhao, X. Gao and Y. Zhang针对OpenMP程序中的barrier提出几种新功能的支持和性能
    发表于 10-28 10:18

    OpenMP优化调研系列文章(3)

    本文调研了4篇与OpenMP优化相关的文献,对优化点分析如下:面向Open64的OpenMP程序优化
    发表于 12-23 16:05

    基于OPENMP多线程技术的运控运算优化

    联邦成员的运算效率直接影响整体仿真效率。因此,本文通过设计乐观约束判别算法以及基于openMP多线程技术优化该成员的运控运算方式,提高运行效率。实验表明,改进后的运控联邦成员大幅提高了光学设施仿真任务执行效率,仿真联
    发表于 11-07 16:33 7次下载
    基于<b class='flag-5'>OPENMP</b>多线程技术的运控运算<b class='flag-5'>优化</b>

    基于OpenMP的多线程速成课程

    The session introduces multi-threading using OpenMP and explaining the differences between vectorization and multi-threading
    的头像 发表于 10-22 06:51 1847次阅读

    基于OF/MPI/OpenMP编程的标准计算

    with standards-based OpenFabrics Interfaces* (OFI), message passing interface (MPI), and OpenMP* programming methods on Intel® Xeon Phi™ processors.
    的头像 发表于 09-10 08:22 2991次阅读

    如何在OpenMP中使用嵌套

    此网络研讨会讨论了使用热门团队在OpenMP中使用嵌套的成功示例,并解释了利用嵌套并行机会的最佳实践。
    的头像 发表于 11-07 06:52 2555次阅读

    OpenMP如何支持现代CPU工作

    OpenMP *是共享内存系统上并行编程的标准。了解它如何支持现代CPU。
    的头像 发表于 11-05 07:11 3498次阅读

    一些对OpenMP进行优化的方法

    本文调研了一些对OpenMP进行优化的方法。
    的头像 发表于 10-18 09:44 1687次阅读