原型变量、原子操作、原子性、内存序

本文深入探讨了原子变量和原子操作在多线程编程中的重要性,强调了它们在提高并发性能时的优势。介绍了CPU缓存一致性的工作原理,包括写直达和写回策略,以及解决缓存不一致问题的一致性协议。此外,还讨论了内存序的概念,阐述了编译器优化重排可能导致的并发问题,以及C++11内存模型中的各种内存序保证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、原子变量、原子操作

  • 锁竞争:互斥锁条件变量、原子变量、信号量、读写锁、自旋锁。
  • 在高性能基础组件优化的时候,为了进一步提高并发性能,可以使用原子变量。
  • 性能:原子变量 > 自旋锁 > 互斥锁
    • 操作临界资源的时间较长时使用互斥锁(粒度大)
    • 如果只操作单个变量的话,可以使用原子变量(粒度小) 进行优化。
  • 给基础类型或者指针加上一个标记 std::atomic<T> 之后它就是原子变量对这些变量的操作就是原子操作
  • 原子变量是一种多线程编程中常用的同步机制,它能确保对共享变量的操作在执行时不会被其它线程的操作干扰,从而避免竞态条件。
  • 原子变量具备原子性,也就是要么全部完成,要么全部未完成。
  • 为什么会使用到原子变量 ?
    • 通常某一个变量对应的操作,其 CPU 的指令是大于 1 个指令的,在多线程环境下,可能会引发竞态,在这种线程不安全的情况下,我们需要为这个变量单独设置一个锁安全的标记 std::atomic<T>从而实现线程安全
    • 多线程环境下,确保对共享变量的操作在执行时不会被干扰,从而避免竞态条件。
std::atomic<T>
is_lock_free; // 是否支持无锁操作
store(T desired, std::memory_order order); // 用于将特定的值存储到原子对象中
load(std::memory_order order); // 用于获取原子变量的当前值

// 访问和修改包含的值,将包含的值替换并返回它原来的值。如果替换成功,则返回原来的值
exchange(std::atomic<T>* obj, T desired);
/* 
比较一个值和一个期望值是否相等,如果相等则该值替换成一个新值,并返回 true,否则不做任何操作并返回 false。
*/
compare_exchange_weak(T& expected, T val, memory_order success, memory_order failure);
/*
compare_exchange_weak 函数是一个弱化版本的原子操作函数,因为在某些平台上它可能会失败并重试。
如果需要保证严格的原子性,应该使用 compare_exchange_strong 函数
*/
compare_exchange_strong((T& expected, T val, memory_order success, memory_order failure);

fetch_add
fetch_sub
fetch_and
fetch_or
fetch_xor

二、原子性

  • 要么都做要么还没做,不会让其它核心看到执行的一个中间状态
  • 单处理器单核心实现原子性:
    • 只需要保证操作指令不被打断。
      • 屏蔽中断 → 不允许操作指令被打断,不让其它线程看到操作指令的中间状态
      • 底层硬件自旋锁 → 为了实现线程切换。
  • 多处理器或多核心实现原子性:
    • 除了要保证操作指令不被打断,还需要避免其它核心操作相关的内存空间
      • 以往的 0x86 lock 指令,锁总线避免所有内存的访问
      • 现在的 lock 指令,锁总线只阻止其它核心对相关内存空间的访问,也就是只锁住相关内存空间
      • 内存总线:CPU 需要通过内存总线访问内存。
      • 磁盘总线:CPU 需要通过磁盘总线访问磁盘。

三、CPU 缓存一致性工作原理

  • 为什么要有 CPU 缓存:为了解决 CPU 运算速度与内存访问速度不匹配的问题,所以在 CPU 和内存之间设置了一些缓存。
    • CPU 和磁盘之间也有一个缓存 → 高速缓冲区(page cache) → 为了解决 CPU 运算速度与磁盘访问速度不匹配的问题。
  • CPU 中有三种缓存:L1L2 是核心独有的,L3 是核心共有的,也就是多个核心共用一个 L3。离核心越近访问速度越快,存储容量越小。
  • CPU 缓存的基本单位:cache line64字节。每次最少读取的数据空间(不管用户要读的数据空间有多小)。
    • flag:标识缓存中的数据是否可用,存储的是缓存的状态值(MESI)。
    • tag:索引数据是否在缓存中、数据在缓存中的位置。
    • data:具体存储的数据。
      在这里插入图片描述
  • CPU 缓存的基础上,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值