2.2 Memory model

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指令只删除处理器的本地独占访问标记
  • 存储独占指令或异常。删除处理器的本地独占访问标记和全局独占访问标记。

原文地址:https://www.cnblogs.com/qiyuexin/p/12623818.html

时间: 2024-10-21 19:23:48

2.2 Memory model的相关文章

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

一.JMM(java memory model)内存模型 从网上淘来二张图: 上面这张图说的是,在多核CPU的系统中,每个核CPU自带高速缓存,然后计算机主板上也有一块内存-称为主内(即:内存条).工作时,CPU的高速缓存中的数据通过一系列手段来保证与主内的数据一致(CacheCoherence),更直白点,高速缓存要从主内中load数据,处理完以后,还要save回主存. 上图说的是,java中的各种变量(variable)保存在主存中,然后每个线程自己也有自己的工作内存区(working me

C# Memory model

Memory Model http://blogs.msdn.com/b/cbrumme/archive/2003/05/17/51445.aspx C# - The C# Memory Model in Theory and Practice https://msdn.microsoft.com/magazine/jj863136 https://msdn.microsoft.com/en-us/magazine/jj883956.aspx

CUDA ---- Memory Model

Memory kernel性能高低是不能单纯的从warp的执行上来解释的.比如之前博文涉及到的,将block的维度设置为warp大小的一半会导致load efficiency降低,这个问题无法用warp的调度或者并行性来解释.根本原因是获取global memory的方式很差劲. 众所周知,memory的操作在讲求效率的语言中占有极重的地位.low-latency和high-bandwidth是高性能的理想情况.但是购买拥有大容量,高性能的memory是不现实的,或者不经济的.因此,我们就要尽量

Deep Analysis Java Memory Model

提纲: •Java内存模型 •volatile关键字 •long和double变量的特殊规则 •原子性,可见性与有序性 •先行发生原则 •Java与线程 1.java内存模型 Java虚拟机规范中试图定义一种java内存模型(Java Memory Model,JMM)来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台上都能达到一致的内存访问效果. 主内存与工作内存: JMM的主要目标是定义了程序中各个变量的访问规则,及虚拟机中将变量存储到内存和从内存中取出变量的底层细节.

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

还是说Memory Model,gcc的__sync_synchronize真是太坑爹了! 时间 2012-01-29 03:18:35  IT牛人博客聚合网站 原文  http://www.udpwork.com/item/6751.html 主题 GCC 嗯,还是说可见性的问题.由于CPU和编译器的乱序执行功能,我们经常不得不在代码中手动插入memory barrier.如果你还不清楚memory barrier是什么,那么请先读这个 http://en.wikipedia.org/wiki

Keil中Memory Model和Code Rom Size说明

源:Keil中Memory Model和Code Rom Size说明 C51中定义变量时如果省略存储器类型,Keil C51编译系统则会按编译模式SMALL.COMPACT和LARGE所规定的默认存储器类型去指定变量的存储区域,无论什么存储模式都可以声明变量在任何的8051存储区范围i,但是把最常用的命令如循环计数器和队列索引放在内部数据区可以显著地提高系统性能.以下介绍一下Keil编译选项Target中的Memory Model和Code Rom Size的设置. Memory Model(

memory model

最近看C++11 atomic发现对memory_order很是不理解,memory_order_relaxed/memory_order_consume/memory_order_acquire/memory_order_release/memory_order_acq_rel/ memory_order_seq_cst.这些都是跟memory model有关 关于memory model,对于线程来说,其实是跟编译器相关的.因为我们的编译器在把C++语言翻译成机器代码的时候,会进行各种优化.

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

前面几篇中,我们谈论了synchronized.final以及voilate的用法和底层实现,都绕不开一个话题-Java内存模型(java memory model,简称JMM).Java内存模型是保证线程安全的基础,主要描述了程序中全序的同步动作在不同线程访问共享全局变量时所体现的原子性.可见性和有序性上的限制. 1.定义 维基百科定义:The Java memory model describes how threads in the Java programming language in

死磕 java同步系列之JMM(Java Memory Model)

简介 Java内存模型是在硬件内存模型上的更高层的抽象,它屏蔽了各种硬件和操作系统访问的差异性,保证了Java程序在各种平台下对内存的访问都能达到一致的效果. 硬件内存模型 在正式讲解Java的内存模型之前,我们有必要先了解一下硬件层面的一些东西. 在现代计算机的硬件体系中,CPU的运算速度是非常快的,远远高于它从存储介质读取数据的速度,这里的存储介质有很多,比如磁盘.光盘.网卡.内存等,这些存储介质有一个很明显的特点--距离CPU越近的存储介质往往越小越贵越快,距离CPU越远的存储介质往往越大

浅析java内存模型--JMM(Java Memory Model)

在并发编程中,多个线程之间采取什么机制进行通信(信息交换),什么机制进行数据的同步? 在Java语言中,采用的是共享内存模型来实现多线程之间的信息交换和数据同步的. 线程之间通过共享程序公共的状态,通过读-写内存中公共状态的方式来进行隐式的通信.同步指的是程序在控制多个线程之间执行程序的相对顺序的机制,在共享内存模型中,同步是显式的,程序员必须显式指定某个方法/代码块需要在多线程之间互斥执行. 在说Java内存模型之前,我们先说一下Java的内存结构,也就是运行时的数据区域: Java虚拟机在执