2.2.4 内存访问的软件顺序
程序流程中指令的顺序并不能保证相对应的内存处理顺序,原因如下
- 处理器可以重新排序一些内存获取用来提高效率,当然,这种改变不能影响指令顺序的行为
- 处理有多个总线接口
- 在内存map中的memory或devices有不同等待状态
- 一些内存获取是缓冲的或者speculative(推测的,感觉这个翻译很牵强,但也不知道怎么翻译)
如果内存获取的顺序十分重要,软件必须包含memory barrier instructions 去强制这个顺序;处理器提供了以下memory barrier instruction:
- DMB: Data Memory Barrier(DMB)指令确保了那些未处理的内存流程在随后的内存流程之前完成
- DSB: Data Synchronization Barrier(DSB)指令确保了未处理的内存事务能在随后的指令执行之前完成
- ISB: Instruction Synchronization Barrier(ISB)确保了所有完成的内存事务的影响被随后的指令指定
可以在如下的例子中用memory barrier instruction指令:
- Vector table(向量表):当程序改变了向量表的入口,然后使能了相关的异常,在这两个操作之间运用DMB指令,这样可以保证:当异常在是能后马上发生的情况下,处理器能够使用新的异常向量;
- Self-modifying code:当程序中包含字修改代码时,在程序中的代码修改部分之后马上运行ISB指令,这样可以却把后续的指令执性应用更新的程序;
- Memory map switching:如果系统包含memory map转换机制,在程序的转换memory map之后运用DSB指令,这样可以确保随后的指令执性能够使用更新的memory map
- Dynamic exception priority change:当异常优先级在异常是即将发生状态或运行状态的时候必须改变,在改变之后运用DSB指令,这样可以确保改变在DSB指令完成之后产生作用
- Using a semaphore in multi-master system:如果系统包含多于一个的总线控制,例如:如果在系统中存在另一个处理器,每一个处理器必须运用DMB指令在每一个信号指令之后,去确保另一个总线控制能够看到内存处理在他们想要它执行的顺序中
- 对于Strongly-ordered memory的内存处理,例如the system control block,不需要用DMB指令
2.2.5 Bit-banding
个人的理解呢,就是建立一种映射关系,使操作更加简便
2.2.6 Memory endianness
小端就是低地址存低位,高地址存高位
2.2.7 Synchoronization primitives
Synchoronization primitives包含:
- Load-Exclusive instruction:用于读取内存位置的值,请求对该位置的独占访问
- Store-Exclusive instruction:用于尝试写入相同的内存位置,将状态位返回到寄存器,其中状态位为0表明线程或进程获得了对内存的独占访问,并且写入成功,1表明线程或进程没有获取对内存的独占访问,且没有写操作
Load-Exclusive and Store-Exclusive instructions:
- word instruction:LDREX and STREX
- halfword instruction:LDREXH and STREXH
- byte instruction:LDREXB and STREXB
为了保证对内存特定位置的读-修改-写,软件必须:
- 用一个Load-Exclusive指令去读特定内存位置的值;
- 按照要求更新位置;
- 用一个Store-Exclusive指令去写一个新的值到内存位置,并检查返回的状态位,0表示成功, 1表示失败
软件可以用synchronization primitives按照以下流程来实现一个信号量:
- 用一个Load-Exclusive指令来从信号量地址读从而检查这个信号量是否空闲的
- 如果信号量是空闲的,用一个Store-Exclusive去写声明值到信号量的地址
- 如果第二步的返回值表明Store-Exclusive成功,那么软件就已经成功声明了这个信号量。然而,如果Store-Exclusive失败,另一个进程也许在软件执行第一步之后已经声明这个信号量
Cortex-M3包含一个独占访问监视器,它可以标记处理器是否已经执行一个Load-Exclusive指令,通过以下方式可以将处理器上的独占访问标志去除:
- 执行CLREX指令
- 执行 Store-Exclusive 指令,不管写是否成功
- 一个异常发生,这意味着处理器可以解决不同新城建信号冲突的问题