Android | SMP Primer-内存一致性模型问题

Posted Justin-Yip

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android | 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)在顺序上都是不一致的。例如,硬件一般会在存储内容传输到内存途中对其进行缓冲,这样存储内容就不会立即传输到内存并对其他核心可见

  • 编译器重排指令
    对指令进行重新排序以提高性能

  • 危险的位操作
    正常情况下,并发访问数据结构中的不同字段不会引入数据争用。然而,这条规则有一个重要的例外情况:CC++ 中连续序列的位字段会被视为单个“内存位置”。在确定是否存在数据争用时,访问这种序列中的任何位字段都会被视为访问所有位字段。

  • 数据争用

    • 什么是数据争用?
      当至少两个线程同时访问相同的普通数据,并且其中至少一个线程对其进行修改时,就会发生数据争用。
避免数据争用的方法
  1. 锁或互斥量

    • 互斥量(C++11 std::mutexpthread_mutex_t
    • Java 中的 synchronized
      可确保某些代码段不会与访问相同数据的其他代码段同时运行。我们将这些工具及其他类似工具统称为“锁”。在访问共享数据结构之前始终获取特定锁并在之后将其释放,可防止在访问数据结构时出现数据争用。这还可以确保更新和访问是原子性的,即无法在中间运行数据结构的其他更新。
  2. 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-内存一致性模型问题

Android | SMP Primer-内存一致性模型问题

CPU 的三大架构 —— numa smp mpp

Hyper-V 性能加速之NUMA

Numa解释

算法数据结构专题「线程锁算法专项」初探CLH队列锁机制原理分析