1. 内存区域、类型及属性

内存被分成不同的区域,不同区域有着不同的类型及属性;内存的类型及属性决定着访问这些区域时的行为。

内存的类型有:

  • Normal,处理器可以为了效率而重新排序事务,或者执行推测性的读取。
  • Device, 处理器将保持相对于其他Device或者Strongly-ordered内存的事务顺序。
  • Strongly-ordered, 处理器将保持相对于其他内存的事务顺序。
  • Execute Never (XN),处理器禁止指令访问。从XN区域获取指令的任何尝试都会导致内存管理错误异常。

内存系统可以缓冲对设备内存的写操作,但不能缓冲对Strongly-ordered内存的写操作。

2. 内存访问的系统顺序

对于大多数由显式内存访问指令引起的内存访问,内存系统不保证访问完成的顺序与指令的程序顺序相匹配,前提是这不会影响指令序列的行为。

通常,如果正确的程序执行取决于按程序流程完成的两次内存访问,软件必须在内存访问指令之间插入一条内存屏障指令。

然而,内存系统确实保证了对设备的访问和强顺序内存的一些顺序。对于两个内存访问指令A1和A2,如果在程序顺序中A1出现在A2之前,则由这两条指令引发的内存访问的顺序:

3. 内存访问的行为

Code, SRAM, 和外部RAM区域都可以存储程序,但是还是推荐使用Code区域运行程序,因为这里可以同时获取指令和访问数据。

MPU,内存包含单元,可以重载默认的内存访问行为。

4. 内存访问的软件顺序

在程序流程的指令顺序不一定总能保证和相应的内存事务顺序一致,这是因为:

  • 处理器可以重新排序一些内存的访问来提高效率,前提是不会影响指令序列的行为。
  • 处理器有多重总线接口
  • 在内存区域中的内存或设备有不同的等待状态
  • 一些内存的访问已被缓存或者被预测到了

如果内存的访问顺序很关键,软件必须包含内存屏障指令:

  • DMB, Data Memory Barrier, 确保显著的内存事务完成在随后的内存事务之前
  • DSB, Data Synchronization Barrier,确保内存事务完成在随后的指令执行之前
  • ISB, Instruction Synchronization Barrier, 确保所有内存事务完成后的效果被随后的指令所识别

比如,在以下情况下使用内存屏障指令:

  • 向量表:如果程序修改了向量表中的入口,然后使能了相应的异常。它们之间可以使用DMB,以保证如果异常在修改入口后立即发生时处理器可以使用新的入口地址。
  • 自我修改代码:如果程序中含有自我修改的代码,在修改完代码后立即使用ISB指令,以保证随后的指令执行的是新程序
  • 内存映射切换:如果系统包含内存映射切换的机制,在程序里切换完内存映射后使用DSB指令,以确保随后的指令用的是更新后的内存映射。
  • 动态异常优先级变更:当一个异常处于挂起或激活状态而必须要修改其优先级时,使用DSB指令在修改完之后,以保证在DSB指令完成后所作的修改生效。
  • 在多主控系统使用信号量:假如系统包含不止一个总线主控,如果其他处理器在系统中在用,那么每一个处理器都必须在信号量指令之后使用一个DMB指令来确保其他总线的主控能够看到内存事务按照被执行的顺序排列。

对Strongly-ordered区域的内存访问,比如SCB,不需要使用DMB指令。

对于MPU编程,使用一个DSB指令后跟着ISB指令或异常返回,以确保新的MPU配置已被随后的指令使用。

5. bit-banding, 位段

  • 在别名(alias)区域写一个词会更新1个位在位段(bit-band)区域
  • alias区域的BIT[0]与bit-band区域的位捆绑
  • alias区域的BIT[31:1]对相应的bit-band区域没有影响,写0x01和写0xff效果一样,写0x00和写0xfe效果也一样。
  • 读取alias区域:0x00000001表示对应bit-band区域的位为1;0x00000000表示该位是0

6. 内存的字节顺序

处理器将内存视为一个线性从0开始递增的字节集合。比如,字节0~3是第1个存储的字;字节4~7是第2个存储的字。

小头格式:

7. 同步原语

Cortex-M4指令集包含成对的同步原语。它们提供了一种非阻塞机制,线程或进程可以使用这种机制获得对内存位置的独占访问。软件可以使用它们来执行一个有保证的读-修改-写内存更新序列,或者用于信号量机制。

一对同步原语包括:

  • 一种负载独占指令:用于读取内存位置的值,请求对该位置的独占访问。
  • 一种存储独占指令:用于尝试写入相同的内存位置,向寄存器返回一个状态位。如果这位是:
    • 0:线程或进程获得对内存的独占访问,写操作成功
    • 1:线程或进程没有获得对内存的独占访问,并且没有执行写操作。

负载独占与存储独占指令对为:

  • 单词指令LDREX和STREX  // Load and store register exclusive.
  • 半字指令LDREXH和STREXH
  • 字节指令LDREXB和STREXB

软件必须使用一个与Store-Exclusive指令相对应的Load-Exclusive指令。

要执行一个有保证的 读-修改-写 内存位置,软件必须:

  1. 使用负载独占指令读取位置的值。
  2. 根据需要更新值。
  3. 使用存储独占指令尝试将新值写回内存位置。
  4. 测试返回的状态位。如果这部分是:
    • 0:读-修改-写成功完成,
    • 1:没有进行写操作。这表明在第1步返回的值可能已经过期。软件必须重试读-修改-写序列,

软件可以使用同步原语实现如下信号量:

  1. 使用负载独占指令从信号量地址读取信号量,以检查信号量是否空闲。
  2. 如果信号量是空闲的,则使用存储独占将声称的值写入信号量地址。
  3. 如果从第2步返回的状态位表明存储独占成功,那么软件就已经获得了信号量。但是,如果存储独占失败,那么在软件执行第1步之后,另一个进程可能已经获得了信号量。

Cortex-M4包含一个独占访问监视器,它标记处理器执行了一个负载独占指令的事实。
如果处理器是多处理器系统的一部分,则系统还全局标记由每个处理器的独占访问寻址的内存位置。

处理器删除它的独占访问标记,如果:

  • 它执行一条CLREX指令
  • 不管写操作是否成功,它都执行一个存储独占指令。
  • 发生异常。这意味着处理器可以解决不同线程之间的信号量冲突。

在多处理器实现中,执行一个:

  • CLREX指令只删除处理器的本地独占访问标记
  • 存储独占指令或异常。删除处理器的本地独占访问标记和全局独占访问标记。

2.2 Memory model的更多相关文章

  1. Java (JVM) Memory Model – Memory Management in Java

    原文地址:http://www.journaldev.com/2856/java-jvm-memory-model-memory-management-in-java Understanding JV ...

  2. 还是说Memory Model,gcc的__sync_synchronize真是太坑爹了

    还是说Memory Model,gcc的__sync_synchronize真是太坑爹了! 时间 2012-01-29 03:18:35  IT牛人博客聚合网站 原文  http://www.udpw ...

  3. memory model

    最近看C++11 atomic发现对memory_order很是不理解,memory_order_relaxed/memory_order_consume/memory_order_acquire/m ...

  4. Keil中Memory Model和Code Rom Size说明

    C51中定义变量时如果省略存储器类型,Keil C51编译系统则会按编译模式SMALL.COMPACT和LARGE所规定的默认存储器类型去指定变量的存储区域,无论什么存储模式都可以声明变量在任何的80 ...

  5. 当我们在谈论JMM(Java memory model)的时候,我们在谈论些什么

    前面几篇中,我们谈论了synchronized.final以及voilate的用法和底层实现,都绕不开一个话题-Java内存模型(java memory model,简称JMM).Java内存模型是保 ...

  6. 【翻译】go memory model

    https://studygolang.com/articles/819 原文链接 Introduction The Go memory model specifies the conditions ...

  7. 并发研究之Java内存模型(Java Memory Model)

    Java内存模型JMM java内存模型定义 上一遍文章我们讲到了CPU缓存一致性以及内存屏障问题.那么Java作为一个跨平台的语言,它的实现要面对不同的底层硬件系统,设计一个中间层模型来屏蔽底层的硬 ...

  8. java学习:JMM(java memory model)、volatile、synchronized、AtomicXXX理解

    一.JMM(java memory model)内存模型 从网上淘来二张图: 上面这张图说的是,在多核CPU的系统中,每个核CPU自带高速缓存,然后计算机主板上也有一块内存-称为主内(即:内存条).工 ...

  9. CUDA ---- Memory Model

    Memory kernel性能高低是不能单纯的从warp的执行上来解释的.比如之前博文涉及到的,将block的维度设置为warp大小的一半会导致load efficiency降低,这个问题无法用war ...

  10. 11 The Go Memory Model go语言内置模型

    The Go Memory Model go语言内置模型 Version of May 31, 2014 Introduction 介绍 Advice 建议 Happens Before 在发生之前 ...

随机推荐

  1. java并发的发布和订阅测试

    现在编码的时候,为了处理消息,大家动不动就上个重器,例如MQ之类的.但很多时候,并不是那么有必要,因为数据量和并发其实远远不够. 可以替代的方案非常多,其中一个是java.util.concurren ...

  2. 【ClickHouse】0:clickhouse学习2之数据类型

    一 :如何查看clickhouse具体支持哪些数据类型? 1:查看官方文档:https://clickhouse.tech/docs/en/sql-reference/data-types/ 2:查看 ...

  3. C#开发一个混合Windows服务和Windows窗体的程序

    很多时候,我们希望服务程序可以直接运行,或者可以响应一些参数,这时候,混合Windows服务和Windows窗体的程序就排上用场了.要实现同时支持Windows服务和Windows窗体,需要在启动的第 ...

  4. Java实现分页的方式有哪些?

    1.手动分页 不使用任何框架,用limt分页 select xx from tab_a limt #{pageNo},#{pageSize} 2.RowBounds分页(不推荐) 这个是内存分页,它的 ...

  5. VUE手稿1

  6. h5使用js拉起微信支付

    近期,业务需求对接了微信支付,做个总结.web网页想要拉起微信支付,有两种方法: H5下单支付 , JSAPI支付 .首先纯前端做不了微信支付,必须配合后端才能通过微信的下单请求.接下来说说这两种方法 ...

  7. eclipse注释取消注释

    方法一:使用Ctrl+/快捷键   1 第1步:在Eclipse中拖动鼠标,选中需要注释的代码,通常为连续多行代码. 2 第2步:按住Ctrl+/快捷键,如图所示. 3 第3步:会发现所选代码被&qu ...

  8. SQLServer 的Distinct

    distinct去除重复的数据(distinct是对整个结果集进行数据重复处理,不是针对某一列) -> 检查返回不重复的数据(对于整条记录不重复才会去除,如ID不一样) 用法:select di ...

  9. 面向对象VS面向过程

    什么是面向对象呢? 对于接触或者熟悉一些编程知识的同学来讲,"面向对象"这个词儿一点儿也不陌生.经常听说XX语言是完全面向对象的编程语言,比如C#.Java这些便是完全面向对象的编 ...

  10. 介绍几款强大实用的 IDEA 插件,助力大家开发【工欲善其事必先利其器】

    俗话说:"工欲善其事必先利其器",本问介绍几款强大实用的 IDEA 插件,助力大家开发. 希望大家做一个聪明又努力的人,而不只是一个努力的人. Alibaba Java Codin ...