不确定 openmp 循环中应该共享或私有什么

2024-04-10

我有一个更新矩阵 A 的循环,我想将其设为 openmp,但我不确定哪些变量应该共享和私有。我本以为只有 ii 和 jj 就可以工作,但事实并非如此。我想我也需要在某个地方进行 !$OMP ATOMIC UPDATE...

该循环仅计算 N 和 N-1 个粒子之间的距离并更新矩阵 A。

            !$OMP PARALLEL DO PRIVATE(ii,jj)
            do ii=1,N-1
                    do jj=ii+1,N
                            distance_vector=X(ii,:)-X(jj,:)
                            distance2=sum(distance_vector*distance_vector)
                            distance=DSQRT(distance2)
                            coff=distance*distance*distance
                            PE=PE-M(II)*M(JJ)/distance
                            A(jj,:)=A(jj,:)+(M(ii)/coff)*(distance_vector)
                            A(ii,:)=A(ii,:)-(M(jj)/coff)*(distance_vector)
                    end do
            end do
            !$OMP END PARALLEL DO

OpenMP 的黄金法则是,在外部作用域中定义的所有变量(有一些例外)默认在并行区域中共享。由于 2008 年之前的 Fortran 中没有局部作用域(即没有BLOCK ... END BLOCK在早期版本中),所有变量(除了threadprivate)是共享的,这对我来说很自然(与伊恩布什不同,我不太喜欢使用default(none)然后在各种复杂的科学代码中重新声明所有 100 多个局部变量的可见性)。

以下是确定每个变量的共享类的方法:

  • N- 共享,因为它在所有线程中应该是相同的,并且它们只读取它的值。
  • ii- 它是循环的计数器,受工作共享指令的约束,因此其共享类预先确定为private。在 a 中明确声明它并没有什么坏处PRIVATE条款,但这并不是真正必要的。
  • jj- 循环的循环计数器,不受工作共享指令的约束,因此jj应该private.
  • X- 共享,因为所有线程都引用并且只能从中读取。
  • distance_vector- 显然应该是private因为每个线程都作用于不同的粒子对。
  • distance, distance2, and coff- 同上。
  • M- 应该出于与以下相同的原因共享X.
  • PE- 充当累加器变量(我猜这是系统的势能)并且应该是归约操作的主题,即应该放入REDUCTION(+:....) clause.
  • A- 这个很棘手。它可以被共享和更新A(jj,:)使用同步构造进行保护,或者您可以使用归约(与 C/C++ 不同,OpenMP 允许在 Fortran 中对数组变量进行归约)。A(ii,:)永远不会被多个线程修改,因此不需要特殊处理。

With reduction over A in place, each thread would get its private copy of A and this could be a memory hog, although I doubt you would use this direct O(N2) simulation code to compute systems with very large number of particles. There is also a certain overhead associated with the reduction implementation. In this case you simply need to add A to the list of the REDUCTION(+:...) clause.

通过同步构造,您有两种选择。您可以使用ATOMIC构造或CRITICAL构造。作为ATOMIC仅适用于标量上下文,您必须“取消向量化”赋值循环并应用ATOMIC分别对每个语句,例如:

!$OMP ATOMIC UPDATE
A(jj,1)=A(jj,1)+(M(ii)/coff)*(distance_vector(1))
!$OMP ATOMIC UPDATE
A(jj,2)=A(jj,2)+(M(ii)/coff)*(distance_vector(2))
!$OMP ATOMIC UPDATE
A(jj,3)=A(jj,3)+(M(ii)/coff)*(distance_vector(3))

您也可以将其重写为循环 - 不要忘记声明循环计数器private.

With CRITICAL无需取消循环向量化:

!$OMP CRITICAL (forceloop)
A(jj,:)=A(jj,:)+(M(ii)/coff)*(distance_vector)
!$OMP END CRITICAL (forceloop)

命名关键区域是可选的,在这种特殊情况下有点不必要,但通常它允许分离不相关的关键区域。

哪个更快?展开与ATOMIC or CRITICAL?这取决于很多事情。通常CRITICAL速度要慢得多,因为它经常涉及对 OpenMP 运行时的函数调用,而原子增量(至少在 x86 上)是通过锁定加法指令实现的。正如他们常说的,YMMV。

概括地说,循环的工作版本应该类似于:

!$OMP PARALLEL DO PRIVATE(jj,kk,distance_vector,distance2,distance,coff) &
!$OMP& REDUCTION(+:PE)
do ii=1,N-1
   do jj=ii+1,N
      distance_vector=X(ii,:)-X(jj,:)
      distance2=sum(distance_vector*distance_vector)
      distance=DSQRT(distance2)
      coff=distance*distance*distance
      PE=PE-M(II)*M(JJ)/distance
      do kk=1,3
         !$OMP ATOMIC UPDATE
         A(jj,kk)=A(jj,kk)+(M(ii)/coff)*(distance_vector(kk))
      end do
      A(ii,:)=A(ii,:)-(M(jj)/coff)*(distance_vector)
   end do
end do
!$OMP END PARALLEL DO

我假设你的系统是三维的。


话虽如此,我同意伊恩·布什的观点,你需要重新思考位置和加速度矩阵在内存中的布局方式。正确的缓存使用可以增强您的代码,并且还允许某些操作,例如X(:,ii)-X(:,jj)进行矢量化,即使用矢量 SIMD 指令实现。

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

不确定 openmp 循环中应该共享或私有什么 的相关文章

  • for 循环语法,其中包含 if 语句

    使用 if 语句编写 for 循环的普遍共识是什么 for int i 0 i lt hi i if some invalid condition continue if another invalid condition continue
  • python 线程是如何工作的?

    我想知道 python 线程是并发运行还是并行运行 例如 如果我有两个任务并在两个线程中运行它们 它们是同时运行还是计划同时运行 我知道GIL并且线程仅使用一个 CPU 核心 这是一个复杂的问题 需要大量解释 我将坚持使用 CPython
  • 遍历多行字符串

    我得到一些数据 def data some useless text n even more n finally interesting text 我怎样才能得到其中 有趣的部分 所以基本上所有行都不是以 开头的 Groovy 的一种选择是
  • 单机Octave并行计算——包和示例

    我想在单台机器 而不是集群 上并行化 Octave 中的 for 循环 前段时间我问了一个关于Octave并行版本的问题Octave并行计算 https stackoverflow com questions 7047840 paralle
  • 如何在MPI中传递2D数组并使用C语言创建动态标签值?

    我是 MPI 编程新手 我有一个 8 x 10 数组 需要用它来并行查找每行的总和 在等级 0 进程 0 中 它将使用 2 维数组生成 8 x 10 矩阵 然后我会用tagnumber 作为数组的第一个索引值 行号 这样 我可以使用唯一的缓
  • 循环遍历服务器上的数据库,并更新数据

    我有一台带有多个数据库的服务器 我需要循环访问这些数据库并更改每个数据库中的一个记录 一个表中的值 如何才能做到这一点 EXEC sp MSForEachDB Use UPDATE dbo MyTable SET MyValue 999
  • 循环遍历多维数组

    我有一个与此类似的 JSON 文件 Pages Name Home Page index php admin Name Admin Page admin index php Template admin MobileTemplate adm
  • 过早退出 Qualtrics 中的循环和合并块

    我目前正在进行一项 Qualtrics 调查 受访者必须解决一长串字谜问题 然后回答一些人口统计问题 为了使变位词部分更容易 我使用了循环和合并块 第一个字段是要解决的变位词 第二个字段是变位词的解决方案 因此调查可以根据受访者的答案来检查
  • VBA:删除数组项后减少循环迭代?

    在 Excel 的 VBA 中 For i 0 To UBound artMaster For j i To UBound artMaster If i lt gt j And artMaster i VDN artMaster j VDN
  • 两个非嵌套循环的大 O 表示法

    对于两个非嵌套的 for 循环 大 O 表示法是什么 Example for int i 0 i
  • 如何判断 OpenMP 是否正常工作?

    我正在尝试以并行模式运行 LIBSVM 但我的问题一般是在 OpenMP 中 根据LIBSVM 常见问题解答 http www csie ntu edu tw cjlin libsvm faq html f432 我已使用 pragma 调
  • 如何在 Ruby 中使用循环输出所有可能的组合?

    我刚刚开始学习编程 并试图编写一个输出所有可能组合的函数 到目前为止 我已经能够找到尺寸 2 的所有可能组合 但我不确定如何使代码保持开放式以处理更大尺寸的组合 某种递归会有用吗 我知道我可以使用内置的组合方法 但我只是想弄清楚如何从头开始
  • MSBuild 未使用所有核心进行构建

    我有一个使用 Visual Studios 2008 配置的项目 当我打开 IDE 并点击构建时 系统上的所有核心都用于构建该项目 但是 当我尝试从命令行构建时 仅使用 1 个核心 这是我正在运行的命令 C Windows Microsof
  • C# 计算元音

    我正在学习 C 编程 并且正在尝试计算元音 我让程序循环遍历句子 但它不返回元音计数 而是仅返回字符串的长度 任何帮助将不胜感激 static void Main int total 0 Console WriteLine Enter a
  • 处理异步并行任务的多个异常

    Problem 多个任务并行运行 所有任务 没有任务或其中任何任务都可能抛出异常 当所有任务完成后 必须报告所有可能发生的异常 通过日志 电子邮件 控制台输出 等等 预期行为 我可以通过 linq 使用异步 lambda 构建所有任务 然后
  • 在一条语句中对多个变量进行相同的赋值

    有没有一种方法可以为不同的变量分配相同的值 而无需在单个语句中构造数组 例如 如果我有变量a b c d and e 我可以分配类似的东西吗 a b c d e 10 0 我知道我可以用一行来做 a 10 0 b 10 0 c 10 0 d
  • 如果 FIND 函数在 vba 中找不到任何内容,那么[重复]

    这个问题在这里已经有答案了 我目前正在自动化执行以下步骤的手动流程 1 提示用户打开一个数据文件并打开文件 2 插入4列 3 使用文件中已有的数据创建格式为 DD MM YYYY TEXT 的唯一字符串 其中文本是变量 4 使用 if 语句
  • 循环遍历数组并删除项目,而不中断 for 循环

    我有以下 for 循环 当我使用splice 要删除一个项目 我发现 秒 未定义 我可以检查它是否未定义 但我觉得可能有一种更优雅的方法来做到这一点 我们的愿望是简单地删除一个项目并继续 for i 0 len Auction auctio
  • Perl Parallel::Forkmanager 不允许收集变量值

    也许因为子进程不知道我的散列 请参阅下面的代码 散列 输出没有收集任何内容 除了写入 tmp 文件之外 还有其他方法来收集该值吗 foreach Item AllItems pid pm gt start Item and next Tem
  • 如何在函数执行后停止 tkinter?

    我在停止 提要 时遇到问题 cancel 参数似乎对 after 方法没有任何影响 尽管 feed stop 被打印到控制台 我正在尝试使用一个按钮来启动源 另一个按钮来停止源 from Tkinter import Tk Button i

随机推荐

  • “双精度数组”和 TDoubleDynArray 之间的区别

    The System Typesunit 声明一个数组类型 TDoubleDynArray array of Double 如果我将一个方法声明为 procedure func x TDoubleDynArray 我注意到这个论点x行为就像
  • 使用 php ajax mysql 创建 3 个依赖下拉列表

    我正在使用 PHP MYSQL 和 JAVASCRIPT AJAX 我有多个下拉列表 我想使用 AJAX 使其相互依赖 其中这些下拉列表包含从 MYSQL 数据库检索的数据 用户从first下拉列表并根据其选择second and thir
  • 如何从矩阵中提取行名?

    我有一个行名称为日期的矩阵 我想将这些行名称提取到一个变量中 然后使用rownames 将这些日期应用到我拥有的另一个矩阵中 假设该矩阵称为 data matrix 每当我跑步时 data matrix 0 我得到了所有日期的打印输出 所以
  • Nodejs TCP连接客户端端口分配

    我使用nodejs在客户端和服务器之间创建了tcp连接 网络模块 https nodejs org api net html 服务器正在侦听已经预定义的端口 并且客户端正在连接到该端口 据我了解客户端的端口是由节点动态分配的 那是对的吗 节
  • 系统()的替代方案

    我最近开始接触C 编程 并且获得了很多经验 我过去的几个程序一直在使用 system 命令 我读过这应该是一个非常糟糕的主意 首先 为什么这是一个坏主意 我在 Linux 上使用它来执行诸如清除屏幕 例如 system clear 和启动程
  • 强制 Intellij IDEA 重新读取所有 Maven 依赖项

    如何强制intellij idea重新读取 更新pom文件中指定的所有依赖项 Press Ctrl Shift A to find actions and input reload you will find the Reload All
  • 如果事件处理程序不存在,则以编程方式在 VB.NET 中添加事件处理程序

    我正在尝试对 ASP NET 网页中的多个控件使用单个事件处理程序 当且仅当事件处理程序尚不存在时 我想在运行时添加事件处理程序 在 C 中 我将如下所示编写 if myTextBox OnTextChanged null myTextBo
  • 为什么 MicroMeter 定时器返回零?

    考虑以下代码 public static void main String args Timer timer Metrics timer item processing for int i 0 i lt 100 i timer record
  • 将项目添加到 ListView,保持滚动位置并且看不到滚动跳跃

    我正在构建一个类似于 Google Hangouts 聊天界面的界面 新消息将添加到列表底部 向上滚动到列表顶部将触发加载以前的消息历史记录 当历史记录从网络传入时 这些消息将添加到列表的顶部 并且不应从触发加载时用户停止的位置触发任何类型
  • 无法确定 Architect 命令 Angular 的项目或目标

    C Users muhiuddin TOWERTECH test testapp gt ng build target production or C Users muhiuddin TOWERTECH test testapp gt ng
  • 如何在开发环境中使用 MobileIron 的 Web@Work 进行测试?

    我有一个可以在任何浏览器中完美运行的网站 现在我想使用 MobileIron 的 Web Work 浏览器将该网站用作书签 以创建一个通过 MobileIron 打包的基本 iOS 应用程序 Web Work的基本介绍在这里 https w
  • java标准序列化顺序

    我想知道以下示例类的属性将按什么顺序序列化 public class Example implements Serializable private static final long serialVersionUID 8845294179
  • 底层提供商无法打开

    HI 我正在使用 VS2010 并使用 Microsoft Entity Framework 4 0 我正在开发一个 Windows 应用程序 我在我的应用程序中绑定了几个组合 工作正常 void BindNatureOfIndustryC
  • 为什么我的 javascript getter/setter 需要下划线?

    执行 Get 或 Put 操作a抛出一个 RangeError 指出Maximum call stack size exceeded指向this a在吸气剂和 在设置器中 let someObject get a return this a
  • apollo graphql 架构 React-admin 初学者

    这些技术是全新的 到目前为止我所看到的让我非常兴奋 我很难找到我所坚持的东西的例子 React admin 的文档建议我的模式说 Posts 遵循 allPosts 和 allPostsMeta allPosts 部分工作没有问题 但自然
  • 如何从自定义视图中访问layout_height?

    我有一个自定义视图 我只是希望访问 xml 布局值layout height 我目前正在获取该信息并将其存储在 onMeasure 期间 但这仅在首次绘制视图时发生 我的视图是 XY 图 它需要尽早知道其高度 以便可以开始执行计算 该视图位
  • 悬停在父 div 上时更改子 div 的背景颜色吗? [复制]

    这个问题在这里已经有答案了 我想在父 div 悬停时更改子 div 的背景颜色 目前 我可以更改颜色 但只能将鼠标悬停在子 div 上 但是 我也想更改父 div 悬停时的颜色 div class content div class log
  • 如何使用 Selenium Safari Webdriver

    我正在尝试使用 Safari WebDriver 并且按照说明进行操作here https code google com p selenium wiki SafariDriverInternals构建 Safari 驱动程序 但现在我不知
  • 稍后如何在 SwiftUI 中访问内容视图的元素?

    假设我有一个像这样的内容视图 struct ContentView View State private var selection 0 var body some View TabView selection selection Cust
  • 不确定 openmp 循环中应该共享或私有什么

    我有一个更新矩阵 A 的循环 我想将其设为 openmp 但我不确定哪些变量应该共享和私有 我本以为只有 ii 和 jj 就可以工作 但事实并非如此 我想我也需要在某个地方进行 OMP ATOMIC UPDATE 该循环仅计算 N 和 N