如果其他线程只读取共享数据,OpenMP 是否需要原子写入?

2023-12-27

我在 C++ 中有一个 openmp 并行循环,其中所有线程都访问一个共享的 double 数组。

  • 每个线程仅在其自己的数组分区中写入。两个线程不能写入同一个数组条目。
  • 每个线程读取其他线程写入的分区。只要双精度值是旧值或更新值(不是读取半写入的双精度值所导致的无效值),数据是否已被拥有该分区的线程更新并不重要。

我是否需要原子写入来确保读取的数据有效(旧的或更新的),或者仅当多个线程尝试在同一位置写入时才需要原子写入?

它似乎可以在有或没有原子写入的情况下工作,但如果没有原子写入,当然速度更快。


你应该使用原子写入和读取以获得正确的可移植程序。指定为标准 http://www.openmp.org/wp-content/uploads/openmp-4.5.pdf:

2.13.6 原子构造

[...]为了避免竞争条件,对 x 指定的位置的所有访问都可以 可能并行发生的情况必须使用原子构造进行保护。

更详细地说:

1.4.1 OpenMP 内存模型的结构

[...]

对变量的单次访问可以使用多个加载或存储指令来实现,因此不能保证相对于对同一变量的其他访问是原子的。

[...]

如果至少一个线程从存储器单元读取并且至少一个线程在没有同步到该同一存储器单元的情况下写入,包括由于如上所述的原子性考虑的情况,则发生数据争用。如果发生数据竞争,则程序的结果是不确定的。

除了原子性之外,还应该考虑可见性:

1.4.3 冲洗操作

内存模型具有宽松的一致性,因为线程的临时内存视图不需要始终与内存保持一致。写入变量的值可以保留在线程的临时视图中,直到稍后将其强制存储到内存中。同样,从变量读取可以从线程的临时视图中检索值,除非强制从内存中读取。 OpenMP 刷新操作强制临时视图和内存之间的一致性。

这意味着,除非您有任何显式或隐式内存刷新,否则无法保证您会看到更新的值。

然而,原子版本并不一定较慢。实现原子操作的编译器知道该体系结构的特定内存模型并可以自由地利用它。事实上 gcc 和 clang 都不是生成昂贵的锁 https://godbolt.org/g/2lFnXs用于原子地写入或读取double在 x86 上,同时这样做是为了原子增量或long double运营。不幸的是,原子可能仍然会阻碍某些优化 - 但如果您省略了这些优化,这些很可能会导致未指定的结果atomic。不要低估编译器优化:对于严格来说不符合标准的明显合理的程序,很容易出现未定义的行为。

至于内存刷新对性能的影响,取决于您的实际算法需要刷新内存的频率。

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

如果其他线程只读取共享数据,OpenMP 是否需要原子写入? 的相关文章

  • 具有“繁忙”线程的 threadPoolExecutor 如何被终止?

    我的问题有点复杂 让我尝试彻底解释一下 但如果您需要更多详细信息 请随时询问我 我会添加它们 我最近 通过实验 了解到 如果线程连续工作 例如 while true 循环中的整数运算 则中断线程对其没有影响 话题继续进行 就像什么都没发生一
  • Java 内存错误:无法创建新的本机线程

    运行 java 服务器时 我在 UNIX 服务器上收到此错误 Exception in thread Thread 0 java lang OutOfMemoryError unable to create new native threa
  • 大量互斥体对性能的影响

    假设我有一个包含 1 000 000 个元素的数组 以及多个工作线程 每个线程都操作该数组中的数据 工作线程可能会使用新数据更新已填充的元素 但每个操作仅限于单个数组元素 并且独立于任何其他元素的值 使用单个互斥锁来保护整个数组显然会导致高
  • HtmlUnit WebClient 超时

    在我之前关于 HtmlUnit 的问题中跳过 HTML 单元中特定的 Javascript 执行 https stackoverflow com questions 14439991 skip particular javascript e
  • 为什么这个简单的 std::thread 示例不起作用?

    尝试编译以下示例g std gnu 0x t1 cpp and g std c 0x t1 cpp但这都会导致示例中止 a out terminate called after throwing an instance of std sys
  • Tweepy 连接中断:IncompleteRead - 处理异常的最佳方法?或者,线程可以帮助避免吗?

    我正在使用 tweepy 处理大型 Twitter 流 关注 4 000 多个帐户 添加到流中的帐户越多 出现此错误的可能性就越大 Traceback most recent call last File myscript py line
  • 处理两个传入的数据流并将它们组合在 python 中?

    我一直在研究Python中线程 多处理异步等的各种选项 作为处理两个传入流并将它们组合起来的方法 有关的信息很多 但示例往往令人费解且复杂 更常见的是将单个任务拆分为多个线程或进程 以加快任务的最终结果 我有一个通过套接字传入的数据流 当前
  • Parallel.ForEachAsync 的实际最大并发任务数

    我预计这段代码需要 1 秒才能执行 public async void Test DateTime start DateTime Now await Parallel ForEachAsync new int 1000 new Parall
  • Delphi线程死锁

    我有时会在销毁某些线程时遇到死锁问题 我尝试过调试该问题 但在 IDE 中调试时似乎从未存在死锁 可能是因为 IDE 中的事件速度较低 问题 当应用程序启动时 主线程会创建多个线程 线程始终处于活动状态并与主线程同步 完全没有问题 当应用程
  • 跟踪 C#/.NET 任务流

    我正在尝试找到一种方法来跟踪异步任务执行流程 以便轻松理解任务 启动它的原始流程是什么 我主要需要它来记录 调试和保留特定执行流的堆栈跟踪 例如 如果我的服务器有来自多个 IP 的许多客户端 并且服务器需要为每个客户端执行一个涉及许多异步操
  • 设置 display:block 后将焦点设置在输入元素上

    我有一个 HTML 内容如下 div class hiddenClass this implies display none span span div
  • Memcached的get和put方法是线程安全的吗

    多线程环境下memcached中的key是否有可能出现乱码 如果是这样 如何以最短的同步时间避免它 使用Java客户端访问memcached服务器 不会 Memcache 将返回某人之前写入的值 而不是乱码 如果您获取 修改 放置 则无法保
  • 从 Java 内部限制 CPU

    我在这个 和其他 论坛中看到了许多具有相同标题的问题 但似乎没有一个问题能完全解决我的问题 就是这个 我有一个 JVM 它占用了托管它的机器上的所有 CPU 我想限制它 但是我不能依赖任何限制工具 技术external到 Java 因为我无
  • 如何在 iPhone 应用程序中运行进程而不阻塞用户界面

    我正在 iPhone 上访问照片库 需要很长时间才能导入我在应用程序中选择的图片 如何在辅助线程上运行该进程 或者我应该使用什么解决方案来不阻塞用户界面 我在这里使用 PerformSelectOnBackground 或 GCD 对示例代
  • Java 同步计数器 - get() 怎么样?

    众所周知这么简单x 不是原子操作 实际上是读 增量 写操作 这就是为什么它应该同步 但是关于get 我读过它也应该同步 但有人能解释一下为什么吗 通过引入来避免内存一致性错误happens before关系 当出现以下情况时该怎么办get
  • ASP.NET 中的 ThreadStaticAttribute

    我有一个需要存储的组件static每个线程的值 它是一个通用组件 可以在许多场景中使用 而不仅仅是在 ASP NET 中 我想用 ThreadStatic 属性来实现我的目标 假设它在 ASP NET 场景中也能正常工作 因为我假设每个请求
  • 在 Oracle 过程中实现多线程

    我正在研究 Oracle 10gR2 这是我的问题 我有一个程序 我们称之为 proc parent 在包内 应该调用另一个过程 让我们调用它 用户创建 我得打电话 用户创建 在一个循环中 它从表中读取一些列 并且这些列值作为参数传递给 用
  • 为什么我的多线程 C 程序在 macOS 上无法运行,但在 Linux 上却完全正常?

    我用 C 语言编写了一个多线程程序 使用 pthreads 来解决 N 皇后问题 它使用生产者消费者编程模型 一位生产者创建所有可能的组合 一位消费者评估该组合是否有效 我使用一个共享缓冲区 一次可以保存一个组合 一旦我有 2 个以上的消费
  • 何时在多线程中使用 易失性?

    如果有两个线程访问全局变量 那么许多教程都说使该变量成为易失性的 以防止编译器将变量缓存在寄存器中 从而无法正确更新 然而 两个线程都访问共享变量需要通过互斥体进行保护 不是吗 但在这种情况下 在线程锁定和释放互斥体之间 代码位于关键部分
  • 易失性变量的读-修改-写操作如何保证线程安全

    我正在阅读 JCIP 但无法理解 3 3 1 中的以下声明 只要您可以确保仅从单个线程写入易失性变量 对共享易失性变量执行读取 修改 写入操作就是安全的 在这种情况下 您将修改限制在单个线程中以防止竞争条件 并且易失性变量的可见性保证可确保

随机推荐

  • C# 动态表名查询

    我想构建一个查询 其中表名是动态的 我将从另一个查询中获取它 这两个查询位于不同的数据上下文中 CODE var tablename from tab in db Tabs where tab id tabid select tab nam
  • 是否有从 Visual Studio 项目中编译 CIL 代码的示例

    我意识到有人询问并回答了 Visual Studio 不支持 CIL MSIL 项目 这MSBuildContrib http msbuildcontrib codeplex com项目有一个 ILASM 任务 允许您在构建时编译 IL 文
  • 如何隐藏Android平板电脑底部系统栏

    我正在开发一个仅适用于平板电脑的应用程序 其中要求是在平板电脑的全屏上运行该应用程序 为此 我在主要活动中使用了以下代码 getWindow requestFeature Window FEATURE NO TITLE getWindow
  • 按时间索引过滤 Pandas DataFrame

    我有一个从早上 6 36 到下午 5 31 的 pandas DataFrame 我想删除时间小于 8 00 00 AM 的所有观察结果 这是我的尝试 df df df index lt 2013 10 16 08 00 00 这没有任何作
  • 更改 ng-multiselect-dropdown 的 css

    我想更改 ng multiselect dropdown 中的 css
  • 为什么在迭代 NumPy 数组时 Cython 比 Numba 慢很多?

    当迭代 NumPy 数组时 Numba 似乎比 Cython 快得多 我可能缺少哪些 Cython 优化 这是一个简单的例子 纯Python代码 import numpy as np def f arr res np zeros len a
  • 使用 Nexus 设置缺少 Maven 依赖项

    我正在尝试构建一个 Maven 项目来测试一些测试软件 Arquillian 我设置了 nexus 并将 jboss 存储库添加到公共组的底部 当我跑步时mvn test我收到这个错误 Missing 1 com sun istack is
  • 同一tomcat的webapp之间共享对象

    我有 2 个 web 应用程序在两个上下文中运行 c1 c2 都紧接在根目录之后 我在 c1 中放置了一个startupListener 来共享一个变量 在 c2 中放置了另一个来检索它 我在 c1 中的启动侦听器是 public void
  • 将列类型更改为导轨中较长的字符串

    在第一次迁移时 我在列上声明content成为字符串 Activerecord 根据注释 gem 将其设置为 string 255 将应用程序推送到使用 postgres 的 Heroku 后 如果我在内容表单中输入长度超过 255 的字符
  • 如何在doc任务中排除java源文件?

    我正在将 sbt 0 11 2 用于混合 Java Scala 项目 我意识到当我运行时doc从 sbt 中运行命令 它不仅为 Scala 源文件创建 scaladocssrc main scala 也适用于 Java 源文件src mai
  • kafka 8 和内存 - 内存不足,Java 运行时环境无法继续

    我正在使用具有 512 兆内存的 DigiOcean 实例 在使用 kafka 时出现以下错误 我不是一个精通java的开发人员 如何调整kafka以利用少量的内存 这是一个开发服务器 我不想为更大的机器支付更多的每小时费用 There i
  • 具有嵌套模块的嵌套路由

    我第一次开发 Angular 2 应用程序 我有与此类似的路由 home projects projects id members projects id members id tasks 从我在互联网上可以找到的所有参考资料 教程和文章中
  • wordpress get_the_category 返回空

    保存新评论后 我可以通过functions php进行重定向 add filter comment post myredirect 我想重定向到产品类别列表 例如 http example org baktec27 product cat
  • C# 中拦截对属性 get 方法的调用

    假设我们有这个类 public class Person public int Id get set public string Name get set 现在 在 C 中是否可以拦截对属性获取方法的调用 运行其他方法并返回该方法的结果而不
  • 将字符串文字分配给 char 数组,如何将字符串文字复制到堆栈上?

    我知道当您执行 char array string 时 字符串文字 string 会从数据段复制到堆栈 字符串文字是否逐字符复制 或者编译器获取字符串文字的起始和结束地址并将整个字符串一次性复制到堆栈中 thanks 只要观察到的结果相同
  • Provider 与 InheritedWidget

    我错了还是我们只是想传递一个值Widget tree Provider https pub dev packages provider只是一个InheritedWidget with a dispose method 是的 Provider
  • Skia 或 Direct2D 如何使用 GPU 渲染线条或多边形?

    这是一道了解2d矢量图形GPU加速渲染原理的题 使用 Skia 或 Direct2D 您可以绘制例如圆角矩形 贝塞尔曲线 多边形 还有模糊等效果 Skia Direct2D 提供基于 CPU 和 GPU 的渲染 For the CPU渲染
  • TreeView ContextMenu MVVM 绑定

    我目前有一个使用 MVVM 模型的 UserControl 该控件中有一个 TreeView 它显示一些项目 我为此 TreeView 添加了一个 HierarchicalDataTemplate 并且在该模板中是项目的 ContextMe
  • MongoDB 无法更新文档,因为 _id 是字符串,而不是 ObjectId

    我正在做一个rest api来在mongo数据库和网络应用程序之间交换数据 这些数据是json格式的 我在更新文档时遇到了麻烦 cannot change id of a document 事实上 在我的 JSON 中 文档的 id 存储为
  • 如果其他线程只读取共享数据,OpenMP 是否需要原子写入?

    我在 C 中有一个 openmp 并行循环 其中所有线程都访问一个共享的 double 数组 每个线程仅在其自己的数组分区中写入 两个线程不能写入同一个数组条目 每个线程读取其他线程写入的分区 只要双精度值是旧值或更新值 不是读取半写入的双