内存模型与同步原语 - 4 在设计同步原语时,我们在考虑什么?

简介: 互斥是指对共享资源的排他性访问,同步是指对进程执行的先后顺序作出妥善安排 Linux 内核中的各种锁机制实际上都是实现“互斥”的语义 ### design principle of locking #### parallesim 在讨论各种锁机制之前,有必要讨论系统的并行度,即有哪些潜在的竞争场景 1. 中断上下文与进程上下文对共享资源的访问,由于中断是异步进行的

互斥是指对共享资源的排他性访问,同步是指对进程执行的先后顺序作出妥善安排

Linux 内核中的各种锁机制实际上都是实现“互斥”的语义

design principle of locking

parallesim

在讨论各种锁机制之前,有必要讨论系统的并行度,即有哪些潜在的竞争场景

  1. 中断上下文与进程上下文对共享资源的访问,由于中断是异步进行的,因而中断与进程是并发执行的,当中断上下文与进程上下文同时对共享资源进行访问时,就有可能形成竞争
  2. 在 UP 与 SMP 系统中,当处理器是可抢占的时,由于可抢占的特性,同一个处理器内进程与进程间是并发执行的
  3. 在 SMP 系统中,多处理器间的进程是严格意义上的并发执行的

parallesim from preemption

在单处理器上,进程之间的抢占是并行度的一大来源,为了排除进程抢占带来的并行度,在锁机制的实现过程中必须关闭抢占

parallesim from SMP

在 SMP 系统中,多处理器之间是严格并发执行的

目前内核中大部分锁机制使用 counter based locking 来排除多处理器之间的并行度,其原理是维护一个整型数据类型的 counter 计数器,计数器的值就表示可用资源的份数,在申请占用资源的时候计数器就加 1,在申请释放资源的时候计数器就减 1

counter based 的锁机制在实现时都需要考虑 atomic 与 barrier 两个维度


atomic

首先,counter based 的锁机制的核心都是整型数据类型的 counter 计数器,需要保证对计数的操作是 atomic 的

现代处理器架构一般都保证对整型数据类型的 load 或 store 操作原生是 atomic 的,但是锁机制中大量涉及的是 add/sub 即 RMW (Read-Modify-Write) 操作,但是处理器架构一般不能保证 RMW (Read-Modify-Write) 操作原生是 atomic 的

  • x86 架构下使用 LOCK 指令来实现 atomic RMW (read-modify-write)
  • ARM 架构下提供 LDREX/STREX 指令来实现 atomic RMW (read-modify-write)

acquire/release barrier

只有 atomic RMW (read-modify-write) 还不够,因为 memory reordering 可能会将 lock 操作之后的内存访问指令重排到 lock 操作之前执行

update counter
---------------------
LOCK
---------------------
critical area

也有可能将 unlock 操作之前的内存访问指令重排到 unlock 操作之后执行

critical area
---------------------
UNLOCK
---------------------
update counter

因而 counter based 的锁机制还需要实现 acquire/release 语义,从而确保 lock 操作之后的内存访问指令不会重排到 lock 操作之前执行

update counter
---------------------
read acquire (LOCK)
---------------------
critical area stay below the line

unlock 操作之前的内存访问指令不会重排到 unlock 操作之后执行

critical area stay above the line
---------------------
write release (UNLOCK)
---------------------
update counter

这就需要在 lock 操作的最后调用 acquire barrier,在 unlock 操作的最开始调用 release barrier,从而确保 lock/unlock 之间的内存访问指令一定位于 lock/unlock 之间

x86 架构下由于只存在 StoreLoad reorder,因而天生满足 acquire/release 语义,因而 x86 架构下以上这两个 barrier 的定义都为空

aarch64 架构下则使用 dmb 指令实现 acquire/release 语义

parallesim from IRQ

以上 atomic、barrier、preemption 三个维度实现的锁机制,不是中断安全的,即并不能排除中断带来的并行度

如果锁机制需要保护的共享资源不会被中断处理程序访问,即只是在 process context 之间共享,那么以上三个维度 atomic、barrier、preemption 实现的锁机制就完全够用了

而如果共享资源还会被中断处理程序访问,也就是共享资源实际上是在 process context 和 interrupt context 之间共享,那么由 process context 这一方发起的上锁的过程中,还必须关闭全局中断

相关文章
|
3月前
|
NoSQL 关系型数据库 MySQL
实时计算 Flink版产品使用问题之全量同步的内存释放该怎么实现
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
3月前
|
SQL 存储 关系型数据库
实时计算 Flink版产品使用问题之同步MySQL多张表的过程中,内存释放依赖于什么
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
4月前
|
存储 安全 Java
Java面试题:请解释Java内存模型,并说明如何在多线程环境下使用synchronized关键字实现同步,阐述ConcurrentHashMap与HashMap的区别,以及它如何在并发环境中提高性能
Java面试题:请解释Java内存模型,并说明如何在多线程环境下使用synchronized关键字实现同步,阐述ConcurrentHashMap与HashMap的区别,以及它如何在并发环境中提高性能
40 0
|
缓存 安全 Unix
C/C++使用Windows的API实现共享内存以及同步
C/C++使用Windows的API实现共享内存以及同步
1519 0
|
存储 缓存 网络协议
内存模型与同步原语 - 1 内存屏障
## Intro ### memory reordering 在介绍 memory barrier 之前,首先需要介绍 memory reordering memory reordering 是指指令实际执行的顺序与代码编写时的顺序不一致,即指令发生重排,通常在以下两个步骤发生 1. compiler reordering (compile time) 2. CP
1060 0
内存模型与同步原语 - 1 内存屏障
|
存储 Java
Java之——内存模型(八种操作+同步规则)
同步八种操作 (1)lock(锁定):作用于主内存的变量,把一个变量标识为一条线程独占状态; (2)unlock(解锁):作用于主内存的变量,把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定;
357 0
内存模型与同步原语 - 3 x86 内存模型
x86-TSO (Total Store Ordering) 是论文 *x86-TSO: A Rigorous and Usable Programmer’s Model for x86 Multiprocessors* 提出的一种 memory model,这是论文作者根据 Intel/AMD specification 的阅读总结,提出的一种总结性的内存模型 虽然 Intel/AMD 官
1020 0
内存模型与同步原语 - 3 x86 内存模型
|
缓存 编译器 Linux
内存模型与同步原语 - 2 内存模型
### Concept #### what is memory model? memory model 的概念通常限定在 multi-processor 架构下讨论 在 multi-processor 架构下,多个处理器之间需要实现信息传递(同步)操作,通常有两种机制用于实现这一操作。 一种是使用 message-passing 机制,在该机制下每个处理器自己有一个 l
420 0
内存模型与同步原语 - 2 内存模型
|
3月前
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
378 0