Atomic Operations (standardized memory model)

2023-10-31

C ++规范未引用任何特定的编译器,操作系统或CPU。它引用了 abstract machine 抽象机,它是对实际系统的概括。

在语言规范中,程序员的工作是为抽象机编写代码。编译器的工作是在具体机器上实现该代码。通过严格按照规范进行编码,可以确定您的代码可以在不使用兼容C ++编译器的任何系统上进行编译和运行,而无论是现在还是50年后。

C ++ 98 / C ++ 03规范中的抽​​象机基本上是单线程的。因此,不可能编写相对于规范“完全可移植”的多线程C ++代码。规范甚至没有说关于内存加载和存储的原子性或加载和存储可能发生的顺序的任何事情,不用管互斥锁之类的事情。

当然,您可以在实践中为特定的具体系统(例如pthread或Windows)编写多线程代码。但是没有标准的方法可以为C ++ 98 / C ++ 03编写多线程代码。

C ++ 11中的抽象机在设计上是多线程的。它还具有定义明确的内存模型;也就是说,它说明了在访问内存时编译器可能会做什么,可能不会做什么。

考虑以下示例,其中两个线程同时访问一对全局变量:

在这里插入图片描述
线程2可能输出什么?

在C ++ 98 / C ++ 03下,这甚至不是“未定义行为”;这个问题本身是没有意义的,因为该标准并未考虑任何被称为“线程”的东西。

在C ++ 11下,结果是未定义行为,因为加载和存储通常不需要是原子的。看起来似乎并没有太大的改善…就其本身而言,不是。

但是,使用C ++ 11,您可以编写以下代码:
在这里插入图片描述
现在事情变得更加有趣了。首先,在此定义行为。现在可以打印线程2 0 0(如果它在线程1之前运行),37 17(如果它在线程1之后运行)或0 17(如果在线程1分配给x之后但分配给y之前运行)。

它无法打印的是37 0,因为C ++ 11中原子加载/存储的默认模式是强制顺序一致性(sequential consistency)。这仅意味着所有加载和存储必须“好像”它们按照您在每个线程中写入它们的顺序发生,而线程之间的操作可以交错,但是系统喜欢。所以原子能的默认行为,同时提供了原子和排序的加载和存储。

现在,在现代CPU上,确保顺序一致性可能很昂贵。特别是,编译器很可能在每次访问之间发出完全成熟的内存屏障( memory barriers )。但是,如果您的算法可以容忍乱序的加载和存储;即,如果它需要原子性但不需要排序;即,如果它可以容忍37 0此程序的输出,则可以编写以下代码:
在这里插入图片描述
CPU越现代化,比上一个示例的运行速度越快。

最后,如果只需要按顺序保留特定的loads 和 stores ,则可以编写:
在这里插入图片描述
这将我们带回到有序的装载和存储位置。因此37 0不可能再是输出,但这样做的开销却很小。 (在这个简单的示例中,预期于结果的顺序一致性相同;在较大的程序中,结果则可能不是。)

当然,如果要查看的唯一输出是0 0或37 17,则只需在原始代码周围包裹一个互斥体Mutexes 即可。

互斥体很棒,并且C ++ 11对其进行了标准化。但有时出于性能原因,您需要较低级别的语言原语 lower-level Language primitive (例如,经典的双重检查锁定模式 double-checked locking pattern)。新标准提供了诸如互斥锁和条件变量之类的高级小工具,还提供了诸如原子类型和各种不同的内存屏障之类的低级小工具。因此,现在您可以完全使用标准指定的语言编写复杂的高性能并发例程,并且可以确定您的代码可以在当今和未来的系统上编译并保持不变。

坦率地说,除非您是专家并且致力于一些严肃的低级代码,否则您应该坚持使用互斥体和条件变量。那就是我打算做的。



参考资料

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

Atomic Operations (standardized memory model) 的相关文章

  • 【chineseocr_lite】踩的坑

    chineseocr lite版本 https github com ouyanghuiyu chineseocr lite git 最重要的电脑环境 v100服务器 cuda10 python3 6 环境对了就成功90 另本环境是cuda

随机推荐

  • UWB自组网定位方案_基于UWB技术的消防应急救援定位解决方案

    目前国内应急救援市场都是基于被动定位应用 在特殊情况下救援也大多处于单兵作战的情况 并不能及时知道自己和自己组员的位置信息和状态 且没有场景感知和室内外一体位置信息结合 使相关救援人员处于更加危险境地 本篇就带大家详细了解一下微能信息针对消
  • JDBC中的Connection

    jdbc中的Connection连接基本用法 package Jdbc import java sql Connection import java sql DriverManager import java sql SQLExceptio
  • Google Sign In error 12500

    接入Google登录遇到12500报错 网上查到的原因是后台配置包的签名哈希值不正确 但是我们的应用并没有使用firebase管理 尝试多次之后终于找到了解决方法 在开发者后台应用管理界面 创建一个新的凭据 类型为Andorid 该凭据下包
  • 层层优化重复代码,我又搞了一个通用模板

    后端思维 最近工作中 我通过层层优化重复代码 最后抽出个通用模板 因此跟大家分享一下优化以及思考的过程 我会先造一个相似的例子 然后一步步带大家如何优化哈 看完一定会有帮助的 优化前的例子 第一步优化 抽取公用方法 第二步优化 反射对比字段
  • 除了李飞飞,那些影响 AI 技术发展的女性工程师

    自 1911 年以来 国际妇女节已经走过了一个多世纪 我们为一个更平等的世界努力过 并且仍将继续努力 近年来 随着数据科学和机器学习的迅猛发展 AI 从业者的需求激增 然而 人工智能领域女性从业者的数量远低于男性 根据 Wired 和 El
  • 〖Web全栈开发②〗—网络编程基础(下)

    Web全栈开发 网络编程基础 下 一 TCP 网络应用程序开发流程 1 TCP 网络应用程序开发流程的介绍 2 TCP 客户端程序开发流程的介绍 3 TCP 服务端程序开发流程的介绍 4 小结 二 socket之send和recv原理剖析
  • Java BIO API及代码测试

    文章目录 0 网络编程 1 JAVA最初的网络应用 BIO 1 1服务端代码编写 1 2客户端代码编写 1 3升级版服务端代码 支持同时处理多连接 1 4再次升级服务端代码 支持浏览器请求 2 拓展学习 ServerSocket 类 及AP
  • 蓝桥杯算法提高VIP-队列操作

    题目 题目链接 题解 模拟队列 代码 include
  • 删除vim打开文件末尾的^M

    最近在Windows下写了一个shell脚本 拿到Linux下执行的时候一直提示找不到文件 但是文件明明就存在 在Linux用vi vim 打开脚本 文件内容不为空 仔细检查脚本内容也没有出错 只是每行 末尾 多出来一个 M 符号 去掉这个
  • Qt使用QTcpSocket及QTcpServer传输文件

    服务端具体代码如下 h include
  • Python学习笔记合集(Pyhton基础总结)

    Python学习笔记合集 Python学习笔记合集 Pyhton基础总结 第一天主要讲了Python基本语句 上 第二天主要讲了Python基本语句 下 第三天主要讲了import导包 库 和Python条件语句 第四天主要讲了Python
  • 闭包【JavaScript基础面试题】

    闭包的定义 如果一个函数能访问外部的变量 那么就形成了一个闭包 闭包形成的原理 当一个普通函数执行结束之后 函数内的变量会被全部销毁 垃圾回收 但是 如果某些变量在函数外部会被用到 那么该变量就不会被销毁 因此形成了闭包 可以看下面的例子
  • [INFO] [copilotIgnore] inactive,github copilot没反应怎么解决

    在使用github copilot的时候 插件不工作 后台出现了这种输出 这种情况下就是它的激活出现了问题 如果账号的使用权没有问题的话 就将该插件disable之后再重新enable 重新观察输出 就会看到copilot在重新链接引擎了
  • C语言头文件和条件编译

    目录 一 条件编译 1 ifdef else endif 2 ifndef 用法 3 if和 elif 4 上述指令的嵌套使用 5 line 和 error 6 pragma 二 include 1 头文件被包含的方式 1 1 本地文件包含
  • 基于 pytorch的 肺部x光片疾病识别

    目录 案例主要流程 数据集下载地址 数据示例 模型结构示意图 ResNet 网络结构图
  • Python基础数据之列表知识(二)

    Python基础数据之列表知识 二 一 列表的特点 二 列表的排序 三 列表的嵌套 1 嵌套的基本使用 2 嵌套的示例 四 列表的循环删除 五 列表相关知识链接 一 列表的特点 1 有序 2 独立 3 列表中的元素可以重复 二 列表的排序
  • 【数据结构】队列的链式实现

    链式队列定义及各类操作 include
  • 目标检测之Dynamic Head: Unifying Object Detection Heads with Attentions

    cvpr2021 论文 https arxiv org pdf 2106 08322v1 pdf 代码 https github com microsoft DynamicHead 1 摘要 作者认为目标检测的头部是由三个部分组成 首先 头
  • openpyxl表格样式设置

    import pandas as pd from openpyxl import Workbook from openpyxl import load workbook from openpyxl styles import Alignme
  • Atomic Operations (standardized memory model)

    C 规范未引用任何特定的编译器 操作系统或CPU 它引用了 abstract machine 抽象机 它是对实际系统的概括 在语言规范中 程序员的工作是为抽象机编写代码 编译器的工作是在具体机器上实现该代码 通过严格按照规范进行编码 可以确