• 忘掉天地
  • 仿佛也想不起自己
bingliaolongBingliaolong  2024-10-08 15:40 Aet 隐藏边栏 |   抢沙发  7 
文章评分 2 次,平均分 5.0

变量的读取

概述

  1. 一般来说,读取一个变量的内容,是从内存里面去取的
  2. 但是,在编译时启用优化选项后,编译器可能会对代码进行优化,以提高执行效率

优化手段-寄存器

  1. 一个常见的优化手段就是将一些频繁访问的变量存储在CPU寄存器中,而不是每次都从内存中读取
  2. 这种优化可以大幅度提升程序的性能

优化手段-寄存器-原因

  1. 寄存器比内存更快
    1. 寄存器是CPU中的高速存储器,访问速度远远快于从主内存中读取数据
    2. 因此,把变量放在寄存器中可以减少访问的延迟
  2. 减少内存访问次数
    1. 编译器会分析程序的执行路径,发现某些变量在特定代码段中频繁使用
    2. 为了避免频繁的内存读写操作,编译器会将这些变量放入寄存器,这样就能减少内存访问的次数
  3. 避免不必要的加载和存储
    1. 编译器可以通过寄存器分配来避免不必要的内存读取和写入操作
    2. 例如,局部变量或者在某些循环体中频繁使用的变量可以通过寄存器直接访问,避免多次加载和存储的开销

优化手段-寄存器-过程

  1. 编译器会在程序的寄存器分配阶段,决定哪些变量可以保存在寄存器中
    1. 这些变量通常是那些生命周期较短、在函数局部作用域中使用的变量
  2. 在启用优化选项时(例如 -O2-O3GCCClang 中),编译器会更加积极地进行寄存器分配
    1. 相应地,那些不需要频繁写回内存的变量,就可能完全留在寄存器中,直到它们不再被使用

注意事项

  1. 寄存器数量有限
    1. 不同的CPU架构提供的可用寄存器数量是有限的,因此,只有部分变量可以被存储到寄存器中
    2. 如果寄存器不够用,编译器还是会把其他变量放回内存

优化手段-寄存器-问题

  1. 寄存器的局部性
    1. 每个线程或CPU核心通常都有自己的寄存器,某些变量的值可能被保存在一个核心的寄存器中,而没有同步回内存中
    2. 如果另一个线程在不同的核心上运行,访问同一个变量,它可能会从内存中读取旧值,而不知道变量在另一个核心的寄存器中已被修改
  2. 缓存一致性问题
    1. 即使没有寄存器优化,不同CPU核心的缓存机制也可能导致多线程访问同一内存位置时,数据不同步
    2. 如果没有特殊的同步机制(如内存屏障),一个线程的修改可能无法及时传播到其他线程看到的内存中

volatile

概述

  1. 为了避免这种问题,C/C++ 提供了 volatile 关键字
  2. volatile 告诉编译器,不要对该变量的读取和写入进行优化,每次都必须从内存中读取,或者写回内存,而不是仅仅使用寄存器的缓存值

具体作用

  1. 禁止寄存器缓存
    1. 当变量声明为 volatile 时,编译器将确保每次读取该变量时,都会从内存中获取最新值,而不是使用寄存器中可能缓存的旧值
    2. 这样,即使变量在一个线程中被修改,另一个线程也能看到正确的修改结果
  2. 禁止指令重排序
    1. 编译器在进行优化时,有时会对指令的执行顺序进行调整
    2. volatile 会告诉编译器不要重排序对这个变量的访问,确保代码按书写顺序执行,避免引发多线程中的竞争条件

解决的问题

  1. 并不保证线程安全
  2. 仅仅保证:
    1. 每次访问该变量时,都会从内存中读取,而不是从寄存器或者CPU缓存中获取值
    2. 写入操作会直接写入内存,而不是仅仅更新寄存器或缓存中的值

示例代码

  1. 这个例子中,flag 是一个共享变量
    1. 如果不使用 volatile,编译器可能会将 flag 缓存到寄存器中,导致 thread1 看到的始终是旧值,无法感知到 thread2 中对 flag 的修改
    2. 通过声明 flagvolatile,编译器将确保 thread1 每次都从内存中读取 flag 的最新值,而不是使用寄存器中的缓存

局限性

  1. 它并不能保证线程安全
    1. volatile 不提供原子性
    2. 也就是说,如果两个线程同时对 volatile 变量进行读写操作,依然可能出现竞争条件,导致数据损坏

怎么解决线程安全问题

  1. 要在多线程中确保变量的正确性,通常需要使用同步机制
    1. 互斥锁(mutex):保证一次只有一个线程访问共享变量
    2. 原子操作:使用 C++ 提供的 std::atomic 进行原子操作

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

bingliaolong
Bingliaolong 关注:0    粉丝:0 最后编辑于:2024-12-13
Everything will be better.

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享