在 C++ 中写入相同值的竞争条件?

2024-03-24

当操作写入单个常量值时,代码中存在竞争条件是否存在任何问题?例如,如果有一个并行循环填充了seen另一个数组中的每个值的数组arr(假设索引越界没有问题)。关键部分可能是以下代码:

//parallel body with index i
int val = arr[i];
seen[val] = true;

由于写入的唯一值是true这是否意味着不需要互斥锁,并且可能会损害性能?即使线程互相踩踏,它们也只是用相同的值填充地址,对吗?


C++ 内存模型不会为您提供写入相同值的免费通行证。

如果两个线程在没有同步的情况下写入非原子对象,则这只是一个竞争条件。竞争条件意味着您的程序执行未定义的行为。程序执行过程中任何地方发生的未定义行为意味着程序的行为(无论是在未定义行为之前还是之后)都不受 C++ 标准的任何限制。

给定的编译器可以自由地提供更自由的内存模型。我不知道有任何这样做。

您必须了解的一件事是 C++ 不是汇编宏语言。它不必生成您脑海中想象的简单汇编程序。相反,C++ 试图让编译器更容易地生成汇编程序,这是一个非常不同的事情。

编译器可以并且确实确定“如果 X 发生,我们会得到未定义的行为;因此在生成代码时,我将围绕 X 不发生的事实进行优化”。在这种情况下,编译器可以prove具有定义行为的程序可能具有相同的val在两个不同的同步线程中。

所有这些都可能在生成任何程序集之前很久就发生。

在汇编级别,某些硬件可能会通过对多字节值进行未对齐的分配来执行有趣的操作。当声称是单线程写入的指令在两个不同的内核中的相同字节上发生时,某些硬件可能(理论上;我在实践中不知道任何情况)引发陷阱。


这就是 C++ 中的 UB。一旦你有了 UB,你就必须在编译器接触到的地方审计你的程序生成的汇编代码。如果你使用 LTO,这意味着在你的整个程序中,至少在调用或与执行 UB 的代码交互的所有地方,都达到了一个不清楚的距离。

只需编写定义的行为即可。只有当这被证明是一个关键任务性能瓶颈时,您才应该花更多的精力来优化它(首先是更快的定义行为,只有当失败时您才考虑 UB)。

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

在 C++ 中写入相同值的竞争条件? 的相关文章

  • 将 Stream 反序列化为 List 或任何其他类型

    尝试将流反序列化为List
  • C# 创建函数队列

    我写了一个名为 QueueManager 的类 class QueueManager Queue functionsQueue public bool IsEmpty get if functionsQueue Count 0 return
  • 起订量要求?违背了目的?

    是否需要虚拟化您想要模拟的所有属性访问器就违背了模拟的目的 我的意思是 如果我必须修改我的对象并虚拟化我想要模拟的每个访问器 我难道不能继承我的类并自己模拟它吗 你的问题非常有效 但如果你仔细想想 没有其他方法可以模拟课程 如果你采用一个接
  • 使用 OpenGL 着色器进行数学计算 (C++)

    我有一个矩阵 例如 100x100 尺寸 我需要对每个元素进行计算 matrix i j tt 8 5例如 我有一个巨大的矩阵 我想使用 OpenGL 着色器来实现该算法 我想使用着色器 例如 uniform float val unifo
  • 如何在编译C代码时禁用警告?

    我正在使用 32 位 Fedora 14 系统 我正在使用编译我的源代码gcc 有谁知道如何在编译c代码时禁用警告 EDIT 是的 我知道 最好的办法是修复这些警告以避免任何未定义 未知的行为 但目前在这里 我第一次编写了巨大的代码 并且在
  • 如何在 Asp.net Gridview 列中添加复选框单击事件

    我在 asp 中有一个 gridview 其中我添加了第一列作为复选框列 现在我想选择此列并获取该行的 id 值 但我不知道该怎么做 这是我的 Aspx 代码
  • 在 MATLAB 中创建共享库

    一位研究人员在 MATLAB 中创建了一个小型仿真 我们希望其他人也能使用它 我的计划是进行模拟 清理一些东西并将其变成一组函数 然后我打算将其编译成C库并使用SWIG https en wikipedia org wiki SWIG创建一
  • 单线程公寓问题

    从我的主窗体中 我调用以下命令来打开一个新窗体 MyForm sth new MyForm sth show 一切都很好 但是这个表单有一个组合框 当我将其 AutoCompleteMode 切换为建议和追加时 我在显示表单时遇到了这个异常
  • 我可以仅在少数情况下关闭模拟吗

    我有一个始终使用模拟的应用程序 但是 当用户以管理员身份登录时 一些操作需要他们写入服务器本身 现在 如果这些用户在实际服务器上没有权限 有些用户没有 则不会让他们写入 我想做的是关闭几个命令的模拟 有没有办法做这样的事情 using Ho
  • 指向字节数组的指针

    由于 Misra C 的要求 我的一位同事想要使用指针声明 但我遇到了一些问题 Misra 安全关键指南 不会让我们纯粹的程序员使用指针 但会让我们对数组字节进行操作 他打算获取一个指向字节数组的指针 因此我们不会在堆栈上传递实际的数组 T
  • 手动将 ClientBase 集合类型从 Array[] 更改为 List<>

    我将自己的 WCF 代理与 Client Base 一起使用 我想做一些类似于 svc util 中的 ct 属性的操作 并告诉代理返回 List 集合类型 我不能使用 List 因为实体由 nhibernate 管理 所以我必须使用 IL
  • 格式化货币

    在下面的示例中 逗号是小数点分隔符 我有这个 125456 89 我想要这个 125 456 89 其他示例 23456789 89 gt 23 456 789 89 Thanks 看看这个例子 double value 12345 678
  • dropdownlist DataTextField 由属性组成?

    有没有一种方法可以通过 C 使 asp net 中的下拉列表的 datatextfield 属性由对象的多个属性组成 public class MyObject public int Id get set public string Nam
  • 在VisualStudio DTE中,如何获取ActiveDocument的内容?

    我正在 VisualStudio 中编写脚本 并尝试获取当前 ActiveDocument 的内容 这是我当前的解决方案 var visualStudio new API VisualStudio 2010 var vsDTE visual
  • 正确使用“extern”关键字

    有一些来源 书籍 在线材料 解释了extern如下 extern int i declaration has extern int i 1 definition specified by the absence of extern 并且有支
  • 将非算术类型作为参数传递给 cmath 函数是否有效?

    给定以下用户定义类型S具有转换功能double struct S operator double return 1 0 以及以下调用cmath http en cppreference com w cpp header cmath使用类型的
  • 设计 Javascript 前端 <-> C++ 后端通信

    在我最近的将来 我将不得不制作一个具有 C 后端和 Web 前端的系统 要求 目前 我对此了解不多 我认为前端将触发数据传输 而不是后端 所以不需要类似 Comet 的东西 由于在该领域的经验可能很少 我非常感谢您对我所做的设计决策的评论
  • #pragma pack(16) 和 #pragma pack(8) 的效果总是相同吗?

    我正在尝试使用来对齐数据成员 pragma pack n http msdn microsoft com en us library 2e70t5y1 28v vs 100 29 aspx 以下面为例 include
  • 如何将对象转换为传递给函数的类型?

    这不会编译 但我想做的只是将对象转换为传递给函数的 t public void My Func Object input Type t t object ab TypeDescriptor GetConverter t ConvertFro
  • 启动画面后主窗口出现在其他窗口后面

    我有一个带有启动屏幕的 Windows 窗体应用程序 当我运行该应用程序时 启动屏幕显示正常 消失并加载应用程序的主窗体 但是 当我加载主窗体时 它出现在包含该应用程序的 Windows 资源管理器目录下 这是运行启动画面然后运行主窗体的代

随机推荐

  • Google 关于推送通知的回应

    我正在创建一个用于 Google 日历集成的应用程序 当任何人手动更改 Google 日历事件时 我试图从 Google 获取通知 因此 我们在 Google 和我的应用程序之间创建了一个通道 现在的问题是 当 google 将响应标头发送
  • 如何编写通用方法来查找最大元素并调用该方法?

    当我试图解决运动问题时来自泛型教程问答 http docs oracle com javase tutorial java generics QandE generics answers html我的答案略有不同 我的回答 public s
  • 完成调试/编码后,如何处理 print()

    致Python专家 我使用了很多 print 来检查变量的值 完成后 我需要删除 print 它非常耗时并且容易出现人为错误 想了解一下你们如何处理 print 是编码时删除还是最后删除 或者有一种方法可以自动删除它或者您不使用 print
  • AngularJS 中的 Rails 路由参数

    我正在尝试构建一个不使用 ngView 的 AngularJS Rails 多页面应用程序 基本上 我想在我的 Rails 应用程序中使用 Angular 的数据绑定和其他功能 同时仍然拥有由我的 Rails 路由确定的视图 到目前为止 它
  • 分别计算每列的不同值

    我可以计算每列的不同值而不枚举它们吗 假设我有一张桌子col1 col2 col3 并且没有其他列 在不明确提及这些列的情况下 我希望得到与以下相同的结果 SELECT count distinct col1 as col1 count d
  • 不同航线如何使用相同的护照策略?

    假设我有这样的代码 var api1 require api1 var api2 require api2 var app express app use api1 api1 app use api2 api2 这是 api1 模块的代码
  • 斯坦福 NLP - VP 与 NP

    我有一个例子 斯坦福 NLP 为句子输出了一个奇怪的解析树 Clean my desk ROOT NP NP JJ Clean NP PRP my NN desk 正如你所看到的 它标记了这个词Clean作为依赖于动词的形容词desk整个短
  • 保持 OpenCV 2 和 OpenCV 3 之间的代码兼容性

    我的库当前使用 OpenCV 2 现在 我正在尝试编译该库以使用 OpenCV 3 似乎一些头文件被移动 一些常量被重命名 例如 CV INTER LINEAROpenCV 3 中未定义 由于我的库需要在 OpenCV 2 和 3 上编译和
  • AmazonRDSEnhancedMonitoringRole 的 Cloudformation 模板

    我正在尝试通过 Cloudformation 模板启动 RDS 堆栈 我想在我的数据库实例上启用增强监控 为了做到这一点 MonitoringRoleArn必须在资源上指定属性 据我了解 这个 ARN 应该指向一个 IAM 服务角色 该角色
  • python urllib2 urlopen 响应

    python urllib2 urlopen 响应
  • 在 eclipse RCP 中安装新插件/功能后,是否有任何方法可以自动从磁盘中清除旧插件/功能?

    我正在构建一个 RCP 应用程序 每个季度都会更新功能 插件 因此 如果用户选择自动更新功能 插件 则将下载更新插件的新 jar 但旧插件仍在使用我不再使用的磁盘空间 我厌倦了删除包含旧 jar 信息的安装历史记录 当我尝试删除它时 它向我
  • 我们什么时候应该使用 RxJS tap 运算符?

    我不明白从the docs https rxjs dev firebaseapp com api operators tap 有人能给我解释一下吗 大多数操作符都按流顺序工作 例如 source pipe map a string gt c
  • 如何将支持的操作系统添加到 Windows 单击一次应用程序清单中?

    我正在尝试将supportedOS标签添加到单击一次应用程序清单中 对于常规应用程序执行此操作的常用方法是将 app manifest 文件添加到包含supportedOS 标记的项目中 如下所示 我删除了自动生成的单击一次清单中已包含的所
  • 在 Swift 中将两字节 UInt8 数组转换为 UInt16

    使用 Swift 我想将 uint8 t 数组中的字节转换为整数 C 示例 char bytes 2 0x01 0x02 NSData data NSData dataWithBytes bytes length 2 NSLog data
  • Vue.js 从 webpack 包中排除文件夹

    我陷入了一个关于 webpack 的非常简单的问题 我有一个使用 vue cli 创建的简单 Vue js 应用程序 我创建了文件夹public Reports我想从捆绑包中排除它 该文件夹包含子文件夹和 PDF 我的项目结构是标准的 di
  • 从边框外部绝对定位

    当我将元素绝对定位在相对元素内时 坐标是从容器的边缘计算的 而不考虑边框 相当于从边框的内侧定位 除了从边框的外侧定位元素之外 还有什么方法可以定位元素吗 例如 如果我有一个没有边框的红色方块 如第一个 则文本会粘在容器的左上角 因为它有t
  • PHP PHAR 归档的优点

    PHP 5 3 有一个新功能称为PHAR如同JAR在JAVA中 它基本上是 PHP 文件的存档 它的优点是什么 我不明白它们在网络场景中有何帮助 除 易于部署 之外的任何其他用途 只需复制一个文件即可部署整个应用程序 开源项目有巨大的好处
  • 从 JavaScript 字符串中去除 U+10000-U+10FFFF

    Tried string replace u10000 u10FFFF g 但可悲的是 u不支持10000 要指定超出 U FFFF 的代码点 您需要查找UTF 16 代理对 https en wikipedia org wiki UTF
  • 放大黑线的阈值

    给定一张图像 如下图所示 我需要将其转换为二进制图像 仅限黑白像素 这听起来很简单 我尝试过两个阈值函数 问题是我无法使用这些函数中的任何一个来获得完美的边缘 任何帮助将不胜感激 我尝试过的过滤器是 RGB 和 HSV 空间中的欧几里得距离
  • 在 C++ 中写入相同值的竞争条件?

    当操作写入单个常量值时 代码中存在竞争条件是否存在任何问题 例如 如果有一个并行循环填充了seen另一个数组中的每个值的数组arr 假设索引越界没有问题 关键部分可能是以下代码 parallel body with index i int