当前位置: 首页 > wzjs >正文

专业的网站建设企业好推建站

专业的网站建设企业,好推建站,bootstrap 网站登录模板,网站代码怎么查看今日文章: 小林coding:CPU 缓存一致性 小林coding:CPU 是如何执行任务的? 目录 CPU 缓存一致性写直达(Write Through)写回(Write Back)多核心缓存一致性 CPU读写与调度问题CPU Cac…

今日文章:

小林coding:CPU 缓存一致性

小林coding:CPU 是如何执行任务的?

目录

    • CPU 缓存一致性
      • 写直达(Write Through)
      • 写回(Write Back)
      • 多核心缓存一致性
    • CPU读写与调度问题
      • CPU Cache **伪共享(False Sharing)**导致缓存失效
      • 避免伪共享
      • 线程调度
        • 任务
        • 调度类种类
        • 完全公平调度(Completely Fair Scheduling)

其他:

往期打卡


CPU 缓存一致性

数据写入 Cache 之后,内存与 Cache 相对应的数据将会不同,需要将数据同步写回内存才能保证数据的一致性

下面介绍两种针对写入数据的方法:

写直达(Write Through)

写直达是保证Cache和内存数据一致最简单的方式,写入数据到Cache时,把数据同时写入内存和 Cache 中,如果是新数据直接写入内存

在这里插入图片描述

写回(Write Back)

写直达频繁访问内存影响性能,写回机制中,写操作新数据仅仅写入Cache,只在替换数据时判断脏数据并写回内存

特殊情况为写未命中,写回策略对于该情况并没有做无意义操作

  1. 为什么写回未命中需要从内存中先读取回来再访问而不是直接写cache ?

    因为需要保证整个 cache line 块和内存数据一致,毕竟写入一般不会刚好是 cache line 块长

  2. 为什么写回未命中不能直接写内存还得写入cache再等写回去?

    因为数据改写后一般有用,用到了还得读,而且可能还会多次修改,必要时再写回内存有助于减少内存访问次数

在这里插入图片描述

多核心缓存一致性

写直达只需要在修改内存时广播事件通知各核心即可,主要看写回策略

写回策略是替换时写回,要实现各核心数据一致性,需要做到两点:

  • 第一点,某个 CPU 核心里的 Cache 数据更新时,必须要传播到其他核心的 Cache,这个称为写传播(Write Propagation);
  • 第二点,某个 CPU 核心里对数据的操作顺序,必须在其他核心看起来顺序是一样的,需要做到隔离性,事务隔离级别一般为串行化(Transaction Serialization)。

在这里插入图片描述

写操作一定要互斥,所以需要互斥锁

事务四大隔离级别:

在这里插入图片描述

写传播和事务串行化的具体实现技术

  • 总线嗅探
    • 写传播最常见的实现方式是总线嗅探(*Bus Snooping*),也就是总线广播,CPU核心监听总线上的广播事件
  • MESI 协议,四种状态标记Cache Line
    • Modified,已修改,脏标记,更新未写回内存,和独占的区别是其他核心发起读取请求时要先写回内存(因为会丢失已修改状态,不写回内存数据就不一致了)
    • Exclusive,独占,不用多核同步,直接修改
    • Shared,共享,相同的数据在多个 CPU 核心的 Cache 里都有,先通过广播让其他核心中该Cache Line 块无效,再更新当前Cache Line块
    • Invalidated,已失效,Cache Block 里的数据已经失效了,不可以读取该状态的数据。

具体例子:

  1. 当 A 号 CPU 核心从内存读取变量 i 的值,数据被缓存在 A 号 CPU 核心自己的 Cache 里面,此时其他 CPU 核心的 Cache 没有缓存该数据,于是标记 Cache Line 状态为「独占」,此时其 Cache 中的数据与内存是一致的;
  2. 然后 B 号 CPU 核心也从内存读取了变量 i 的值,此时会发送消息给其他 CPU 核心,由于 A 号 CPU 核心已经缓存了该数据,所以会把数据返回给 B 号 CPU 核心。在这个时候, A 和 B 核心缓存了相同的数据,Cache Line 的状态就会变成「共享」,并且其 Cache 中的数据与内存也是一致的;
  3. 当 A 号 CPU 核心要修改 Cache 中 i 变量的值,发现数据对应的 Cache Line 的状态是共享状态,则要向所有的其他 CPU 核心广播一个请求,要求先把其他核心的 Cache 中对应的 Cache Line 标记为「无效」状态,然后 A 号 CPU 核心才更新 Cache 里面的数据,同时标记 Cache Line 为「已修改」状态,此时 Cache 中的数据就与内存不一致了。
  4. 如果 A 号 CPU 核心「继续」修改 Cache 中 i 变量的值,由于此时的 Cache Line 是「已修改」状态,因此不需要给其他 CPU 核心发送消息,直接更新数据即可。如果 A 号 CPU 核心的 Cache 里的 i 变量对应的 Cache Line 要被「替换」,发现 Cache Line 状态是「已修改」状态,就会在替换前先把数据同步到内存。

在这里插入图片描述

CPU读写与调度问题

CPU Cache **伪共享(False Sharing)**导致缓存失效

①. 假设 1 号核心绑定了线程 A,2 号核心绑定了线程 B,线程 A 只会读写变量 A线程 B 只会读写变量 B,但变量 A 和 变量 B 的数据位于同一块

在这里插入图片描述

②. 1 号核心读取变量 A,A 和 B 的数据都会被加载到 Cache,并将此 Cache Line 标记为「独占」状态。

在这里插入图片描述

③. 2 号核心开始从内存里读取变量 B,此时 1 号和 2 号核心的 Cache Line 状态变为「共享」状态。

在这里插入图片描述

④. 1 号核心修改变量 A,核心2Cache Line失效,核心A状态变为「已修改」状态

在这里插入图片描述

⑤. 之后如果A,B线程交替修改A、B变量,就会发生伪共享,每次修改都要写回内存,重新读取,Cache 并没有起到缓存的效果

多个线程同时读写同一个 Cache Line 的不同变量时,而导致 CPU Cache 失效的现象称为伪共享(False Sharing)。

避免伪共享

在 Linux 内核中存在 __cacheline_aligned_in_smp 宏定义,是用于解决伪共享的问题。

在这里插入图片描述

比如对于存在a、b两个变量的结构体,可以将 b 的地址设置为 Cache Line 对齐地址

在这里插入图片描述

Java 并发框架 Disruptor 使用「字节填充 + 继承」的方式,来避免伪共享的问题。

在这里插入图片描述

根据 JVM 对象继承关系中父类成员和子类成员,内存地址是连续排列布局的,因此 RingBufferPad 中的 7 个 long 类型数据作为 Cache Line 前置填充,而 RingBuffer 中的 7 个 long 类型数据则作为 Cache Line 后置填充,这 14 个 long 变量没有任何实际用途,更不会对它们进行读写操作。

经过前后填充,无论怎么加载RingBufferFields都不会和其他RingBufferFields加载到一个Cache,所以多线程间不会出现伪共享问题

一句话总结就是要保证独占占据的全部Cache Line

线程调度

任务

在 Linux 内核中,进程和线程都是用 task_struct 结构体表示的,区别在于线程的 task_struct 结构体里部分资源是共享了进程已创建的资源,比如内存地址空间、代码段、文件描述符等

没有创建线程的进程,是只有单个执行流,它被称为是主线程。如果想让进程处理更多的事情,可以创建多个线程分别去处理,但不管怎么样,它们对应到内核里都是 task_struct。

在这里插入图片描述

Linux 内核里的调度器,调度的对象就是 task_struct,文章中把这个数据结构称为任务。

在这里插入图片描述

任务有不同的优先级以及响应要求,优先级数值越小越优先,在 Linux 系统中主要分为两种:

  • 实时任务,对系统的响应时间要求高,优先级小于100算实时任务
  • 普通任务,响应时间没有很高的要求,优先级在100~139范围算普通任务

nice表示优先级的修正数值,它与优先级(priority)的关系是:

priority(new) = priority(old) + nice

nice 值是映射到 100~139,这个范围是提供给普通任务用的,因此 nice 值调整的是普通任务的优先级。

指定nice值启动任务

在这里插入图片描述

调整运行中任务的nice值

在这里插入图片描述

改变任务的优先级以及调度策略

在这里插入图片描述

调度类种类

在这里插入图片描述

Deadline 和 Realtime 这两个调度类,都是应用于实时任务的,这两个调度类的调度策略合起来共有这三种,它们的作用如下

  • SCHED_DEADLINE:是按照 deadline 进行调度的,距离当前时间点最近的 deadline 的任务会被优先调度;(执行最快要到期的任务)
  • SCHED_FIFO:同优先级先来先服务,高优先级抢占
  • SCHED_RR:同优先级时间片轮转,高优先级抢占

而 Fair 调度类是应用于普通任务,都是由 CFS 调度器管理的,分为两种调度策略:

  • SCHED_NORMAL:普通任务使用的调度策略;
  • SCHED_BATCH:后台任务的调度策略,不和终端进行交互,因此在不影响其他需要交互的任务,可以适当降低它的优先级。

每个 CPU 都有自己的运行队列(Run Queue, rq),队列中包含三种调度类的运行队列

调度类有优先级Deadline > Realtime > Fair

先从 dl_rq 里选择任务,然后从 rt_rq 里选择任务,最后从 cfs_rq 里选择任务。因此,实时任务总是会比普通任务优先被执行。

在这里插入图片描述

完全公平调度(Completely Fair Scheduling)

这个算法的理念是想让分配给每个任务的 CPU 时间是一样,于是它为每个任务安排一个虚拟运行时间 vruntime,如果一个任务在运行,其运行的越久,该任务的 vruntime 自然就会越大,而没有被运行的任务,vruntime 是不会变化的。

当然为了区分优先级,需要考虑权重值

内核中会有一个 nice 级别与权重值的转换表,nice 级别越低的权重值就越大

在这里插入图片描述

其中NICE_0_LOAD可以视为常量

往期打卡

暑假读书笔记第二天

暑假读书笔记第一天

http://www.dtcms.com/wzjs/32068.html

相关文章:

  • 企业全称网站杭州网站排名seo
  • 福州微信网站开发seo排名系统源码
  • 株洲网站制作公司2023搜索最多的关键词
  • 望京网站建设公司搜索大全引擎
  • 三合一网站建设方案推广链接点击器网页
  • 重庆南岸网站建设qq推广软件
  • 牛商网 做的p2p网站西安网页设计
  • 上海网站建设制作公司国内网络营销公司排名
  • 福建厦门网站建设网站策划书
  • 学网站建设的软件seo教程 百度网盘
  • 初学者wordpress商城模板企业seo优化
  • flash代码做网站教程我想在百度发布信息
  • 南宁网站seo游戏推广怎么做
  • 经典网站欣赏百度搜索风云榜下载
  • 网站 配色表最近有新病毒出现吗
  • wordpress帝国cms谷歌优化工具
  • 网站建设价格a去找真甲先生媒体宣传推广方案
  • 织梦做的网站图片路径在哪里自己建网站需要钱吗
  • 相亲网站男人拉我做外汇seo数据是什么意思
  • 文化网站前置审批seo快速排名源码
  • 阜宁网站制作费用百度关键词推广工具
  • 购物网站常用的多组图左右轮播的js图片特效代码矿产网站建设价格
  • 犀牛云做网站外贸企业网站推广
  • windows 建设网站国内新闻摘抄2022年
  • 北京专业网站建设公司公司网站制作费用
  • 广州网站建设怎么做网站友情链接购买
  • 都江堰做网站seo怎么做新手入门
  • 网站如何做延迟加载网络营销组合策略
  • 大连网站建设找简维科技域名查询网站入口
  • 个人域名备案有什么风险seo广告优化多少钱