为什么会有c++内存模型

1. 引言

c++的内存模型主要解决的问题是多线程的问题。怎么理解多线程呢?单核时候,只有1个CPU内核处理多线程,各线程之间随着时间的推进,会不断的切换,如下图形便于理解。

实际上线程间的切换是非常快的,所以从人感受的视角,感觉到3个进程独占cpu在执行各自的任务。如果每个线程的变量是独立的,那么多个线程间的运行结果则不会出现问题。但是,如果有一个变量同时被多个线程更改,那么就可能出现问题。

   实际上,高级语言的一行代码,编译成机器码,则需要多个机器码指令。当线程切换时,CPU会保存上个线程的一套通用寄存器和状态寄存器,之后切换到下一个线程的通用寄存器和状态寄存器。打个比方,a的初始值5,线程1执行到以下高级语言代码时,切换下一线程2,此时通用寄存器会保存现场,a变量在线程1中通用寄存器值为5。

a += 10;   (线程1中更改变量a))

恰巧线程2会执行以下代码也修改了变量a。

a + =20; (线程2中更改变量a)

线程2完整的执行了以上代码,此时a的值为25。但是再次切换到线程1的时候,恢复线程1的现场,保存变量a的通用寄存器并不知道a的值已经被改变成25了,它仍然以为变量a的值为5,经过运行后,把变量的值变成了15。然而,编写代码的人的预期值可能是35,因为他认为变量a的初始值为5,线程1执行+10指令,线程2执行+20指令,所以他认为a的值为35。

出现以上不符合预期的结果,总结如下,

多个线程同时修改同一个变量,且在更改变量的时刻,发生了线程切换的事情,cpu内部的通用寄存器保存了现场,而再次返回现场时,这个共享变量已经被别的线程修改过了,不再是原来的值了,但是,当前线程并不知道。

2. CPU和编译器的优化

       然而,高级语言的代码逻辑和实际执行的机器码指令情况并不相同,但是产生的效果是一样。先从CPU架构的硬件差异性说起。一般而言,单核的CPU的理想原型如下:

多核的CPU的理想原型如下

       实际上,CPU核中大面积的集成电路是内核Cache。 在CPU Core和RAM之间,还有共三层的Cache结构(L1/L2/L3),此外还有Store Buffer (SB),且SB和L1 是每个Core独享,而L2是两个Core共享,L3是所有Core共享,模型总结如下

     引入Cache也是有原因了,CPU执行指令速度非常快,只占用几个指令周期,但是从RAM加载机器指令的几百个指令周期。如果CPU直接从RAM中加载机器指令的话,会严重的拖慢CPU的效率,因为CPU等待指令加载。

      引入了Cache,解决了CPU等待的问题,但却产生了很多新的问题,例如Cache的一致性,Cache的缺失,Cache的乒乓效应等等,为了解决这些问题,各CPU平台( X86 / IA64 / ARM / Power…)都有自己的解决方案,软件层面(编译器)也会有对应的优化。这导致了CPU执行的程序,并不是你写的那个版本,只是从结果上看不出差别而已。如果你曾经单步调试过一个release版本的程序,你会发现运行过程很怪异,居然没有沿着你的代码顺序执行。因为,要是严格按照你的代码顺序执行,编译器和CPU都会抱怨,说执行效率很低速度很慢。
       要了解内存模型,还是要先谈谈一些重要的优化,包括编译器和CPU/Cache方面。优化主要包括

  • Reorder
  • Invent
  • Remove

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/618571.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Guava里一些比较常用的工具

随着java版本的更新提供了越来越多的语法和工具来简化日常开发,但是我们一般用的比较早的版本所以体验不到。这时就用到了guava这个包。guava提供了很多方便的工具方法,solar框架就依赖了guava的16.0.1版本,这里稍微介绍下。 一、集合工具类…

《手把手教你》系列基础篇(八十六)-java+ selenium自动化测试-框架设计基础-Log4j实现日志输出(详解教程)

1.简介 自动化测试中如何输出日志文件。任何软件,都会涉及到日志输出。所以,在测试人员报bug,特别是崩溃的bug,一般都要提供软件产品的日志文件。开发通过看日志文件,知道这个崩溃产生的原因,至少知道触发崩…

Linux 添加启动服务--Service

1,服务配置service文件 Service 服务的实际作用是开启后自动启动服务,运行一些不须要登录的程序,任务。 实例1、上电自动连接WIFI热点 1.1 新建.service文件 /etc/systemd/system/wificonnect.service [Unit] DescriptionService [wifico…

使用 Fn Project 搭建无服务平台

目录 下载 脚本直接下载 下载可执行文件 上传 启动 Fn 服务 初始化 Fn 工程 创建 app 部署 function 调用 function JSON 入参 官方文档 下载 有两种下载方式 脚本直接下载 直接在服务器执行该命令即可 curl -LSs https://raw.githubusercontent.com/fnproject/…

记一次Oracle DG备库实例宕分析

一、问题现象 同事反馈国外点在国内的XXX备库实例宕,尝试将该实例重启,结果重启报如下错误,未能正常启动该数据库。 Standby crash recovery failed to bring standby database to a consistent point because needed redo hasnt arrived yet…

乐写9612手写板实测故障

闲鱼上淘了二手的 ①需要驱动很强的usb口,老usb口会不识别,尤其是笔记本容易不识别,非常容易出现下面这种问题: ②需要microsoft2013以上的,兼容性做的比较差 ③由于可视化,导致数据线容易烧,…

GEE非参数趋势分析(Mk-Sen)

趋势分析是寻找感兴趣的东西正在增加的地方,或者 减少多少。更具体地说,本教程演示了 使用非参数 Mann-Kendall 检测影像中的单调趋势 测试是否存在增加或减少的趋势以及 Sen 的斜率 量化趋势的幅度(如果存在)。本教程还显示 估计…

缓存与数据库的数据一致性解决方案分析

在现代应用中,缓存技术的使用广泛且至关重要,主要是为了提高数据访问速度和优化系统整体性能。缓存通过在内存或更快速的存储系统中存储经常访问的数据副本,使得数据检索变得迅速,从而避免了每次请求都需要从较慢的主存储&#xf…

OSI七层网络模型 —— 筑梦之路

在信息技术领域,OSI七层模型是一个经典的网络通信框架,它将网络通信分为七个层次,每一层都有其独特的功能和作用。为了帮助记忆这七个层次,有一个巧妙的方法:将每个层次的英文单词首字母组合起来,形成了一句…

腾讯云优惠券详细介绍及领券步骤详解

随着云计算技术的不断发展和普及,越来越多的企业和个人开始选择使用云服务来满足自身的需求。腾讯云作为国内领先的云服务提供商,以其稳定、高效、安全的服务赢得了广大用户的信赖。为了回馈广大用户,腾讯云经常推出各种优惠活动,…

时间序列模型:lag-Llama

项目地址:GitHub - time-series-foundation-models/lag-llama: Lag-Llama: Towards Foundation Models for Probabilistic Time Series Forecasting 论文地址:https://arxiv.org/pdf/2310.08278.pdf hugging-face镜像:https://hf-mirror.c…

THS6.0.1.0开启健康检查(by lqw)

可以在节点管理器或者分组管理的编辑配置里添加以下信息: 之后点监控,点击实时指标,点击HTTP集群统计: 下图是配置并生效的效果: 也可以使用頁面配置: 推荐使用tcp形式,有的应用后端可能不支持http…