如何惯用地打破嵌套并行 (OpenMP) Fortran 循环?

2023-12-22

这是顺序代码:

do i = 1, n
   do j = i+1, n
      if ("some_condition(i,j)") then
         result = "here's result"
         return
      end if
   end do
end do

除了以下之外,是否有更清晰的方法来同时执行外循环的迭代:

  !$OMP PARALLEL private(i,j)
  !$OMP DO 
  do i = 1, n     
     !$OMP FLUSH(found)
     if (found) goto 10
     do j = i+1, n        
        if ("some_condition(i,j)") then
           !$OMP CRITICAL
           !$OMP FLUSH(found)
           if (.not.found) then           
              found = .true.
              result = "here's result"
           end if
           !$OMP FLUSH(found)
           !$OMP END CRITICAL
           goto 10
        end if
     end do
10   continue
  end do
  !$OMP END DO NOWAIT
  !$OMP END PARALLEL

迭代的顺序i-loop 可以是任意的,只要some result被发现(只要满足"some_condition").


看来您的顺序代码具有依赖性,使其不适合并行化。假设 i 和 j 的多个值使“某个条件”为真 - 那么 i 和 j do 循环的执行顺序决定首先找到这些条件中的哪一个并设置结果的值,然后返回语句结束对“某些条件”为真的其他情况 i,j 的搜索。在顺序代码中,do 循环始终以相同的顺序执行,因此程序的操作是确定性的,并且始终会找到使“某些条件”为真的 i 和 j 的相同值。在并发版本中,各种循环 i 以非确定性顺序执行,因此从运行到运行不同的 i 值可能是找到真正的“某些条件”的第一个 i 值。

也许您作为一名程序员知道 i 和 j 只有一个值会导致真正的“某种条件”?在这种情况下,短路执行似乎没问题。但 OpenMP 规范表示“除了 DO 语句之外,关联循环中的任何语句都不会导致分支 循环之外”,因此不允许内循环中的某些内容中止输出循环。如果总是只有一个真实的“某些条件”,则可以删除“返回”并浪费 CPU通过让线程在找到一种情况后寻找“某种条件”是否为真,这可能需要花费一些时间。这可能仍然比顺序程序更快。使用缩放器“结果”变量,它仍然可能不合规,依赖于执行顺序。您可以将其更改为“减少”,对结果求和,或将结果作为维度 (n) 的一维数组返回。如果您需要找到“某些条件”为 true 的 i 的最小值,您可以使用 Fortran 内在函数 minloc 从数组结果中获取该值。

具有许多“刷新”和“关键”指令的解决方案可能不会比顺序版本更快。

UPDATE:基于多个结果是可能的并且任何结果都可以的澄清,一种并行方法是返回多个结果并让顺序代码挑选一个——将“结果”放入一维数组而不是缩放器中。您可以短路内部 j 循环,因为它与“omp do”指令不“关联”,因此“结果”只需为 1D,根据 i 的范围确定尺寸。所以像这样:

program test1

integer :: i, j
integer, parameter :: n = 10
integer, dimension (n) :: result

result = -999

!omp parallel default (shared) private (i, j)
!omp do
do i = 1, n
   inner: do j = i+1, n
      if ( mod (i+j,14) == 0 ) then
         result (i) = i
         exit inner
      end if
   end do inner
end do
!omp end do
!omp end parallel

write (*, *) 'All results'
write (*, *) result

write (*, *)
write (*, *) 'One result'
write (*, *) result ( maxloc (result, 1) )

end program test1
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何惯用地打破嵌套并行 (OpenMP) Fortran 循环? 的相关文章

  • 尝试读取名单后返回的状态不是预期的

    我想从文件中读取名单 但在名单不存在的情况下实现捕获选项 从我读到的here http msg ucsf edu local programs IBM Compilers Fortran html pgs lr76 htm我期望状态为 84
  • R:使用带有 .Call 和 C/C++ 包装器的 Fortran 子例程而不是 .Fortran 的优点?

    我有一个 R 包 它使用大量 Fortran 子例程来进行递归线性代数计算的嵌套循环 很大程度上依赖于 BLAS 和 LAPACK 例程 作为 Fortran 的接口 我使用 Fortran功能 我刚刚读过乔纳森卡拉汉的博客文章 http
  • OpenMP:无法并行化嵌套 for 循环

    我想将循环与其中的内循环并行化 我的代码如下所示 pragma omp parallel for private jb ib shared n Nb lb lastBlock jj W WT schedule dynamic private
  • 如何格式化整数以仅具有所需的大小?

    我一直在尝试以下代码 program hello write i9 10 end program hello 并改变格式字符串 尝试使写入输出的字符串大小恰好满足表示整数所需的大小 但到目前为止我无法管理它 如何在 Fortran 中编写
  • 终止 Julia 数组理解中的 For 循环

    我在 Julia 中有以下代码行 X i i 2 for i in 1 100 if i 2 5 0 基本上 它返回一个元组列表 i i 2 from i 1 to 100如果剩余的i 2 and 5为零 我想做的是 在数组理解中 跳出 f
  • MPI_Type_Create_Hindexed_Block 生成派生数据类型的错误范围

    使用Fortran 我尝试为动态分配的结构构建派生数据类型 但它得到了新类型的错误范围 代码如下 PROGRAM MAIN IMPLICIT NONE INCLUDE mpif h INTEGER I INTEGER MYID NUMPRO
  • 如何在 makefile 中拥有正确的 .mod 顺序

    我正在尝试用 Fortran 为我的项目创建一个 Makefile 并使其可在现在的项目中重用 我经过多次尝试后得出的 Mkefile 如下 问题是它在少数情况下工作正常 但现在我有这个文件 main f90 初始 f90 参数 f90 函
  • Fortran 内部计时例程,哪个更好? cpu_time 或 system_clock

    当对 FORTRAN 程序进行计时时 我通常只使用命令call cpu time t 然后我偶然发现call system clock count count rate count max 这似乎做了同样的事情 然而 在更加困难的庄园里 我
  • 当我使用并行代码时,为什么我的计算机没有显示加速?

    所以我意识到这个问题听起来很愚蠢 是的 我使用的是双核 但我尝试了两个不同的库 Grand Central Dispatch 和 OpenMP 并且当使用 clock 来对带有和不带有使平行的话 速度是一样的 根据记录 他们都使用自己的并行
  • Fortran90 中 BLAS 函数返回零

    我正在学习在Fortran90中使用BLAS 并使用子例程编写了一个简单的程序SAXPY https software intel com en us mkl developer reference fortran axpy和函数SNRM2
  • 在 if-else 语句中使用标签和中断

    我有这段代码 它在特定条件下 当 x 和 y 都等于零时 从数组生成随机数 我想让控件跳转到标签 但该控件在任何情况下都不会跳转到标签 我想知道我这样做是否正确 int arr 0 1 2 Random rn new Random labe
  • 在 VSCode Fortran 调试中检查从另一个模块导入的变量

    我正在调试一些包含许多 Fortran 模块的代码 其中一些模块彼此共享变量 不幸的是 带有 VScode 的 gdb 在调试时似乎无法检查导入的变量 目前 当我需要检查导入的变量时 唯一的方法是停止调试 并手动更改代码以包含等于导入变量的
  • 使用 Cygwin64 的 Fortran MPI

    我正在使用 Codeblock IDE 编写和编译我的 Fortran 程序 现在我想将 MPI 包含到我的 GNU Fortran 编译器中 在遵循 GNU GCC 编译器的一些指南之后 我突然想到我需要为 MPICH2 设置以下内容 有
  • 将 FORTRAN 对象传递给 C,反之亦然

    我有我的 Fortran 对象 即 this object a this object b this object c 我想将它传递给用 C 编写的代码 我主要是一名 FORTRAN 程序员 而且我很少接触 C 我正在使用iso c bin
  • Fortran 指针数组

    同样 Fortran 中的指针数组 好吧 我有一个派生类型 type t context pointer type t context pointer p ctx end type t context pointer 当我在主程序中执行以下
  • 2 个数组/图像相乘的多线程性能 - 英特尔 IPP

    我正在使用英特尔 IPP 来进行 2 个图像 数组 的乘法 我使用的是 Intel Composer 2015 Update 6 附带的 Intel IPP 8 2 我创建了一个简单的函数来乘以太大的图像 整个项目已附后 见下文 我想看看使
  • 在 Visual Studio 2010 中从 Fortran 调用 C++ 函数

    我想从 Fortran 调用 C 函数 为此 我在 Visual Studio 2010 中创建了一个 FORTRAN 项目 之后 我将一个 Cpp 项目添加到该 FORTRAN 项目中 当我要构建程序时出现以下错误 Error 1 unr
  • 如何在fortran中调用和使用另一个子程序中的子程序?

    我正在编写一个程序 其中主程序包含许多子例程和函数 为了构造主程序的这些子程序之一 假设是子程序 A 我需要使用另一个子程序 假设是 B 我的问题是 如何调用子程序A并使用子程序B 我是初学者 我已经搜索了很多 但没有找到我清楚理解的东西
  • 从代码中覆盖 OMP_NUM_THREADS - 真正的

    到目前为止我能找到的所有答案都建议致电omp set num threads 虽然对于大多数情况来说这是一个正确的答案 但它对我不起作用 在内部 调用omp set num threads导致创建每线程 ICV 或修改 如果当前线程已经有一
  • openmpi 忽略错误:无法识别 mca 接口

    今天早上 我升级了 gfortran 从 4 7 到 6 1 0 和 OpenMPI 从 1 10 到 2 0 1 编译器 我写了这个简单的程序 program main use mpi f08 implicit none

随机推荐

  • iPad 上的 HTML5 视频 CSS 背景颜色

    目前是否可以有效设置 HTML5 视频元素的背景颜色 关于 HTML5 音频和视频 http developer apple com library safari documentation AudioVideo Conceptual Us
  • iOS 汇编代码

    我想在苹果 iOS 上尝试一些 ARM 汇编代码 只是出于教育目的 我想从 Xcode 中的一些内联代码开始 我的理解是 我需要为 iOS 设备进行编译 例如我的 iPhone 这意味着我需要每年支付 99 美元的会员费 我不认为我可以在
  • 如何使用 .Net 反射按名称搜索属性(忽略大小写)?

    我有以下代码行片段 用于按名称搜索实例的属性 var prop Backend GetType GetProperty fieldName 现在我想忽略 fieldName 的大小写 所以我尝试了以下方法 var prop Backend
  • Python 从字典中写入 JSON 临时文件

    我正在开发一个 python 3 6 项目 在该项目中我需要从 Python 字典编写 JSON 文件 这是我的字典 deployment name sec deployment credentials type type1 project
  • Python openCV matchTemplate 在带有遮罩的灰度图像上

    我有一个项目 我想在图像中找到一堆箭头 如下所示 ibb co dSCAYQ使用以下模板 ibb co jpRUtQ 我在 Python 中使用 cv2 的模板匹配功能 我的算法是将模板旋转 360 度并为每次旋转进行匹配 我得到以下结果
  • 借用的价值寿命不够长,因在闭包中使用而移动 E0597

    我正在 Actix Web 上迈出第一步 但是这个关闭导致我出错 derive Deserialize Serialize Debug Copy Clone pub struct PaginationQuery pub limit Opti
  • 如何使用 Gradle 在没有第一个目录的情况下提取?

    我正在尝试提取一个不带 PARENT 目录的依赖 zip 文件 在使用 Gradle 提取时排除一些文件 这是我所拥有的 这有效 但感觉不对 我希望有更好的方法来做到这一点 我正在提取的 Zip 文件 jar tf parent folde
  • 是否定义了宏 X?

    我尝试编译the code http cpp sh 8vrep使用选项 C 14 define X static cast
  • 我不知道我错过了什么(乌龟)

    我在用着Trinket运行我的python 我已经修改它好几天了 它一直给我这个错误 Traceback most recent call last File tmp sessions 5ecd67058b43cfc0 main py li
  • iframe 标签内的 html 的用途是什么?

    我在某处读过一次 它是后备内容 但当 src 加载失败时它不会显示 p text p In the 当前规格 https html spec whatwg org multipage iframe embed object html the
  • vb.net datagridview 的问题

    您好 下面的代码在单击特定单元格时打开领导者的详细视图 我试图做到这一点 以便当单击一个单元格时 它会将具有所选单元格的 LeaderID 的任何事件的行位置添加到数组 le 中 然而这行代码 If dgdEvents Rows n Cel
  • 超出表达式递归级别

    不知道为什么下面的例子会出现错误 a 1 a gt 0 echo y echo n y a x a gt 0 echo y echo n n a a a gt 0 echo y echo n bash a expression recurs
  • 使用 Maven 在 Tomcat 中动态运行 WAR,如何添加类路径条目以便只有 Tomcat 可以看到它们?

    场景是这样的 我有一个 web 应用程序 我想使用 tomcat maven plugin 动态运行tomcat 运行目标 http mojo codehaus org tomcat maven plugin run mojo html 问
  • 如果应用程序处于 GC 中,如何可靠地获取 JVM 核心转储?

    我正在尝试查找 java 应用程序中内存泄漏的原因 我需要为某个进程获取堆转储longGC 循环 Jmap 在这种情况下不起作用 因为应用程序被挂起 而且堆非常大 不幸的是 jmap 在我获取的核心转储上抛出 UnknownOopExcep
  • xhgui不保存任何数据

    我已经在 Ubuntu 计算机上安装了所有先决条件 并将以下内容添加到我的 apache 虚拟主机文件中 php admin value auto prepend file var www xhgui external header php
  • 使用 Doxygen 的 Qt 风格文档? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 如何使用 Doxygen 生成 Qt 风格的文档 Trolltech 的 C Qt 或 Riverba
  • trigger.io - 无法再创建 ipa 文件

    我通常使用trigger io 生成适用于iOS 的ipa 文件 现在 当我想生成文件时 我收到以下错误消息 运行 usr bin codesign 时失败 codesign allocate 对象 Users mherceg Deskto
  • 使用 vb.net 或 c# 的 Textbox_KeyPress 事件

    我的要求是我正在尝试为我的母语开发一个文本编辑器 也就是说 我正在尝试使用 unicode 字符开发泰米尔语文本编辑器 当我按下键盘上的按键 例如英文字符 k时 我想替换两个字符 例如 H0b95 H0bcd 我如何实施这个概念 是否可能
  • 在 MySQL 中搜索表情符号

    我有一个看起来像这样的字符串 现在 当我的应用程序将此字符串推入其 utf8 mysql 数据库列时 它在 MySQL CLI 中看起来像这样 如果我选择convert mystring using utfmb4 它看起来仍然是这个样子 如
  • 如何惯用地打破嵌套并行 (OpenMP) Fortran 循环?

    这是顺序代码 do i 1 n do j i 1 n if some condition i j then result here s result return end if end do end do 除了以下之外 是否有更清晰的方法来