Android | SMP Primer-内存一致性模型问题
Posted Justin-Yip
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android | SMP Primer-内存一致性模型问题相关的知识,希望对你有一定的参考价值。
SMP Primer
–This article is excerpted from Google’s official about Automotive , please indicate the source for reprinting–
Terms
- SMP : Symmetric Multi-Processor
Symmetric Multi-Processor (对称多处理器)
- SMP 特点
- 两个或多个相同的 CPU 核心共同访问主内存
多核心CPU同步问题
-
CPU缓冲
单处理器(包括 x86 和 ARM)通常在顺序上是一致的。线程似乎以交错方式执行,因为操作系统内核会在线程之间切换。大多数 SMP系统(包括 x86 和 ARM)在顺序上都是不一致的。例如,硬件一般会在存储内容传输到内存途中对其进行缓冲,这样存储内容就不会立即传输到内存并对其他核心可见 -
编译器重排指令
对指令进行重新排序以提高性能 -
危险的位操作
正常情况下,并发访问数据结构中的不同字段不会引入数据争用。然而,这条规则有一个重要的例外情况:C
或C++
中连续序列的位字段会被视为单个“内存位置”。在确定是否存在数据争用时,访问这种序列中的任何位字段都会被视为访问所有位字段。 -
数据争用
- 什么是数据争用?
当至少两个线程同时访问相同的普通数据,并且其中至少一个线程对其进行修改时,就会发生数据争用。
- 什么是数据争用?
避免数据争用的方法
-
锁或互斥量
- 互斥量(
C++11
std::mutex
或pthread_mutex_t
) Java
中的synchronized
块
可确保某些代码段不会与访问相同数据的其他代码段同时运行。我们将这些工具及其他类似工具统称为“锁”。在访问共享数据结构之前始终获取特定锁并在之后将其释放,可防止在访问数据结构时出现数据争用。这还可以确保更新和访问是原子性的,即无法在中间运行数据结构的其他更新。
- 互斥量(
-
Volatile
/atomic
变量
能做的:
只确保对单个变量的单独访问是原子性的(在 C++ 中,这通常会扩展到简单的读取-修改-写入操作,例如增量操作。Java 需要特殊的方法调用才能实现此类操作)
不能做的
不能直接用于阻止其他线程干扰较长的代码序列。volatile
不靠谱
在 C 和 C++ 中,对 volatile 数据的访问可以通过访问非 volatile 数据进行重新排序,且没有原子性保证。因此,volatile 不能用于在可移植代码中的线程之间共享数据,即使在单处理器上也是如此。C volatile 通常不会阻止硬件对访问进行重新排序,因此其本身在多线程 SMP 环境中更不实用。这就是 C11 和 C++11 支持 atomic 对象的原因。您应该改为使用这两项。C 和 C++ volatile 声明是用途非常特殊的工具,可阻止编译器对 volatile 访问进行重新排序或将其移除。这对于访问硬件设备寄存器的代码、映射到多个位置的内存或与 setjmp 连接很有帮助
C/C++ atomic 变量或 Java volatile 变量可用于阻止在其他变量上出现数据争用的情况。如果声明 flag 具有类型 atomic、atomic_bool (C/C++) 或 volatile boolean (Java),且初始值为 false,则以下代码段不存在数据争用的情况:
线程 1 | 线程 2 |
---|---|
A = … | while (!flag) |
flag = true | … = A |
线程 2 需要等待 flag 设置完成,因此必须在线程 1 中为 A 赋值之后才能在线程 2 中访问 A,而不能并发进行。因此,A 上不存在数据争用的情况。对 flag 的争用不属于数据争用,因为 volatile/atomic 访问不属于“普通的内存访问”。
实现方法需要充分阻止或隐藏内存重新排序,使代码(如之前的石蕊测试)的行为与预期相符。这通常会使 volatile/atomic 内存访问的开销明显高于普通访问。
尽管上述示例不存在数据争用的情况,结合使用锁与 Java 中的 Object.wait() 或 C/C++ 中的条件变量通常可更好地解决问题,这样做就不会在无尽的等待中耗尽电池电量。
More details , plz see
SMP Primer for Android
以上是关于Android | SMP Primer-内存一致性模型问题的主要内容,如果未能解决你的问题,请参考以下文章
Android | SMP Primer-内存一致性模型问题