小林图解系统-二.硬件结构 2.5CPU是如何执行任务的?

news2025/1/15 6:51:09

CPU如何读取数据的?

CPU访问L1 Cache速度比访问内存快100倍,有高速缓存的目的:把Cache作为CPU与内存之间的缓存层,减少对内存的访问频率

所有CPU Cache Line是CPU从内存读取数据到Cache的单位。 64字节

CPU加载数组里面连续的多个数据到Cache里,因此应该按照物理内存地址分布的顺序去访问元素,Cache命中率就会提高。在我们不使用数组,而是使用单独的变量的时候,会由Cache伪共享的问题,Cache伪共享问题上是一个性能杀手,我们应该规避。

伪共享是什么,如何避免?

双核心CPU两个CPU核心并行运行两个不同线程,同时从内存读取两个不同数据,分别是类型为long的变量A和B,这个两个数据的地址在物理内存上是连续的,如果Cache Line 是64字节,并且变量A在Cache Line的开头,那么这两个数据位于同一个Cache Line 中,因为Cpu Cache Line是CPU从内存读取数据到Cache的单位,所以这两个数据被同时读入到两个CPU核心中各自Cache中。

分析伪共享的问题

分析MESI协议:

1.最开始变量A和B都还不在Cache里面,假设1号核心绑定了线程A,2号核心绑定线程B,线程A只会读写变量A,线程B只会读写变量B

2.1号核心读取变量A,由于CPU从内存读取数据到Cache的单位是Cache Line,也正好A和B同属一个Cache Line,所以A和B的数据都会加载到Cache,并标记Cache Line 为独占

3.2号核心开始从内存里读取变量B,同样读取Cache Line大小的数据到Cache,也包含了A和B,此时1和2号核心的Cache Line变为共享

4.1号核心需要修改变量A,发现是共享状态,广播给2号核心,通知2号核心把Cache中对应的Cache Line标记为[已失效],然后1号核心对应的Cache Line状态变成已修改,并修改变量A。

5.2号核心修改变量B,发现2号核心的Cache 对应的Cache Line已失效,另外1号核心也有相同数据,且为已修改,所以要先把1号核心的Cache 对应的Cache Line写回内存,然后2号核心再从内存读取Cache line大小的数据到Cache,最后把变量B修改到2号核心的Cache,并标记为已修改。

虽然变量 A 和 B 之间其实并没有任何的关系,但是因为同时归属于一个 Cache Line ,这个 Cache Line 中的任意数据被修改后,都会相互影响,从而出现 ④ 和 ⑤ 这两个步骤。

因此,这种因为多个线程同时读写同一个Cache Line的不同变量时,而导致CPU Cache失效的现象称为伪共享

避免伪共享的方法

对于经常修改的数据,避免放在同一个Cache Line中,否则就会伪共享

Linux中,__cacheline_aligned_in_smp宏定义,用于解决伪共享问题。

  • 如果在多核系统中,该宏定义是__cacheline_aligned,也就是Cache Line的大小;
  • 而在单核系统里,该宏定义是空的

举例:

struct test {
    int a;
    int b;
}

a,b物理地址连续,可能位于同意个Cache Line

为了防止伪共享

struct test {
    int a;
    int b __cacheline_aligned_in_smp;
}

这样就不会再同一个Cache line中了,消耗空间,提升性能


CPU是如何选择线程的?

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

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

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

根据任务优先级以及相应要求分为两种,优先级的数值越小,优先级越高

  • 实时任务,对系统的响应时间要求很高,也就是要尽可能快的执行实时任务,优先级在0-99
  • 普通任务,响应时间没有很高要求,优先级在100-139

调度类

分为了这几种调度类,如下图。

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

SCHED_DEADLINE:按照deadline进行调度,举例当前时间点最近的deadline的任务会优先调度

SCHED_FIFO:对于相同优先级的任务,按先来先服务,但是优先级更高的任务可以插队

SCHED_RR:对于相同优先级的任务,轮流的运行,每个任务有一定的时间片,当完成时间片的任务会被放到队列尾部,保证相同优先级任务的公平性,但是高优先级的任务依然可以插队。

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

SCHED_NORMAL:普通任务使用的调度策略

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

完全公平的调度
基于CFS的调度算法,完全公平调度(Completely Fair Scheduling)。

想让分配给每个任务的CPU时间是一样的,于是它为每个任务安排了一个虚拟运行时间vruntime,运行越久,该任务的vruntime会越大,而没有被运行的任务,Vruntim 是不会变化的。

在CFS算法调度的时候,会优先选择vruntime少的任务,同时计算虚拟运行时间还要考虑普通任务的权重值(nice级别越低,权重值越大)

CPU运行队列

多任务的数量基本都远超CPU核心数量,因此需要排队

事实上,每个CPU都有自己的运行队列(Run Queue,rq),用于描述在此CPU上所运行的所有进程,其队列包含三个运行队列,Deadline运行队列dl_rq,实时任务运行队列rt_rq和CFS运行队列cfs_rq,其中cfs_rq是用红黑树来描述的,按Vruntime大小来排序的,最左侧的叶子节点,就是下次会被调度的任务。

调整优先级

如果启动任务,默认都是普通任务,调度类是Fair,由CFS调度器管理:实现任务运行的公平性,保障每个任务的运行的时间差不多的。

总结

理解 CPU 是如何读写数据的前提,是要理解 CPU 的架构,CPU 内部的多个 Cache + 外部的内存和磁盘都就构成了金字塔的存储器结构,在这个金字塔中,越往下,存储器的容量就越大,但访问速度就会小。

CPU 读写数据的时候,并不是按一个一个字节为单位来进行读写,而是以 CPU Cache Line 大小为单位,CPU Cache Line 大小一般是 64 个字节,也就意味着 CPU 读写数据的时候,每一次都是以 64 字节大小为一块进行操作。

因此,如果我们操作的数据是数组,那么访问数组元素的时候,按内存分布的地址顺序进行访问,这样能充分利用到 Cache,程序的性能得到提升。但如果操作的数据不是数组,而是普通的变量,并在多核 CPU 的情况下,我们还需要避免 Cache Line 伪共享的问题。

所谓的 Cache Line 伪共享问题就是,多个线程同时读写同一个 Cache Line 的不同变量时,而导致 CPU Cache 失效的现象。那么对于多个线程共享的热点数据,即经常会修改的数据,应该避免这些数据刚好在同一个 Cache Line 中,避免的方式一般有 Cache Line 大小字节对齐,以及字节填充等方法。

系统中需要运行的多线程数一般都会大于 CPU 核心,这样就会导致线程排队等待 CPU,这可能会产生一定的延时,如果我们的任务对延时容忍度很低,则可以通过一些人为手段干预 Linux 的默认调度策略和优先级。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1839102.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【千帆AppBuilder】你有一封邮件待查收|未来的我,你好吗?欢迎体验AI应用《未来信使》

我在百度智能云千帆AppBuilder开发了一款AI原生应用,快来使用吧!「未来信使」:https://appbuilder.baidu.com/s/Q1VPg 目录 背景人工智能未来的信 未来信使功能介绍Prompt组件 千帆社区主要功能AppBuilderModelBuilder详细信息 推荐文章 未来…

【APP移动端性能测试】第一节.APP应用架构、环境和敏捷开发模型介绍

文章目录 前言一、APP应用架构二、APP项目环境 2.1 后端项目环境 2.2 前端项目环境三、Scrum敏捷开发模型 3.1 Scrum敏捷模型基础介绍 3.2 Scrum敏捷开发开发流程总结 前言 一、APP应用架构 (1)APP应用架构 (2&#xff0…

C++240618

1> 思维导图 2> 完善对话框,点击登录对话框, 如果账号和密码匹配,则弹出信息对话框,给出**提示”登录成功“** ,提供一个 **OK按钮**,用户点击**OK后**,**关闭登录界面**, 跳转…

Canonical Juju 的一个奇怪编排部署

一周前的一个项目扩容出现了异常,进行了操作回滚,未对线上业务造成损失。 现象是这样的: 通过基于 Canonical Juju-GUI 在一组节点上部署了某个组件,在把这组节点添加到集群后,有4个节点上出现了同一组件的2个instanc…

Postman文件数据导入导出

前言 不同的接口测试工具如Postman、Apipost、Apifox创建的接口文档都是互通的,都可以互相兼容使用。我们就不需要在3个不同测试工具都去创建,只要在一个工具上创建,想要在其他接口测试工具上使用就运用导入和导出功能即可。 Postman、Apip…

爆赞!GitHub首本Python开发实战背记手册,标星果然百万名不虚传

Python (发音:[ paiθ(ə) n; (US) paiθɔn ] n. 蟒蛇,巨蛇 ),是一种面向对象的解释性的计算机程序设计语言,也是一种功能强大而完善的通用型语言,已经具有十多年的发展历史,成熟且稳定。Python 具有脚本语言中最丰富…

【接口自动化测试】第二节.Requests库和接口对象封装

文章目录 前言一、Requests库 1.1 Requests介绍 1.2 Requests发送请求 1.3 Requests查看响应 1.4 案例1登录接口调试-获取验证码 1.5 案例2登录接口调试-登录 1.6 归纳小结二、接口对象封装 2.1 当前代码待优化问题 2.2 接口对象封装思…

互联网应用主流框架整合之SpingMVC运转逻辑及高级应用

Spring MVC处理器的执行过程 在SpringMVC的流程中,它会把控制器的方法封装为处理器(Handler),为了更加灵活,SpringMVC还提供了处理器的拦截器,从而形成了一条包括处理器和拦截器的执行链,即HandlerExecutionChain&…

Linux-安装及管理程序

目录 一、Linux应用程序基础 1、应用程序与系统命令的关系 2、 典型应用程序的目录结构 3、常见的软件包封装类型 二、RPM包管理工具 1、RPM包管理器 2、RPM软件包 ​3、RPM的命令格式 4、RPM命令的常用选项 5、RPM安装 三、 yum安装 1、yum源介绍 1.1、本地yum源 …

给日期加上15天

// 给当前日期加上15天 function toAndTimeFifteen(params) {let startDate new Date(params); // 创建一个Date对象表示2024年5月31日startDate.setDate(startDate.getDate() 15); // 给当前日期加上15天let dateString formatDate(startDate)// 转换时间格式return dateSt…

自动水位雨量站:用于水库防汛预警

TH-SW2自动水位雨量站是一种现代化的监测设备,主要用于水库等水域的防汛预警系统。它通过集成水位和雨量监测功能,为水库的管理和调度提供实时、准确的数据支持。 工作原理: 自动水位雨量站通过内置的水位计和雨量计实时监测水库的水位变化和…

C++封装TCP类,包括客户端和服务器

头文件 XTcp.h #ifndef XTCP_H #define XTCP_H#ifdef WIN32 #ifdef XSOCKET_EXPORTS #define XSOCKET_API __declspec(dllexport) #else #define XSOCKET_API __declspec(dllimport) #endif #else #define XSOCKET_API #endif#include <string> XSOCKET_API std::string…

宁德时代华北首座电池工厂在北京开工

6月18日&#xff0c;由宁德时代与北汽集团、京能集团、小米集团等共同投资建设的北京时代电池基地项目开工仪式在北京举行。 北京市相关政府代表&#xff0c;宁德时代董事长兼CEO曾毓群&#xff0c;北汽集团董事长张建勇&#xff0c;京能集团副总经理张凤阳&#xff0c;小米集…

第6章 设备驱动程序(4)

目录 6.5 块设备操作 6.5.5 请求结构 6.5.6 BIO 6.5.7 提交请求 6.5.8 I/O调度 6.5.9 ioctl实现 本专栏文章将有70篇左右&#xff0c;欢迎关注&#xff0c;查看后续文章。 6.5 块设备操作 6.5.5 请求结构 struct request { //放在请求队列上&#xff0…

BFS 1块、算多少次

目录 1.矩阵内部的1块 2.从1开始&#xff0c;1或乘2&#xff0c;计算要多少次达到n 3.迷宫路径 1.矩阵内部的1块 #include <iostream> #include <vector> #include <cmath> #include <string> #include <cstring> #include <queue> usi…

现代谱估计分析信号的功率谱(1)---AR 模型谱估计

本篇文章是博主在通信等领域学习时&#xff0c;用于个人学习、研究或者欣赏使用&#xff0c;并基于博主对通信等领域的一些理解而记录的学习摘录和笔记&#xff0c;若有不当和侵权之处&#xff0c;指出后将会立即改正&#xff0c;还望谅解。文章分类在通信领域笔记&#xff1a;…

1951–2021年欧洲地区木本植物的格网物候数据集

本数据集包含1951–2021年欧洲地区&#xff08;3457′N – 723′N&#xff0c;253′W – 403′E&#xff09;6种木本植物的逐年展叶始期和开花始期格网数据&#xff0c;空间分辨率为0.1&#xff0c;时间分辨率为1天。数据集的质量评估表明&#xff0c;欧洲地区各物种展叶始期和…

车载语音识别系统语音数据采集标注案例

随着人工智能技术的不断发展&#xff0c;其在我们日常生活工作场景中的应用也越来越普及&#xff0c;人工智能技术在不同场景的普及大大的提高了我们日常生活、工作的高效性和便利性。以我们的日常出行为例&#xff0c;车载语音识别系统便是一种典型的人工智能应用场景。 车载…

大咖专栏 | AI 时代下,我们可以拥有怎样的数据库?

Hi&#xff0c;各位朋友们&#xff0c;我是 KaiwuDB 高级架构师赵衎衎。 KaiwuDB 始于万物互联时代下千万条数据洪流中&#xff0c;我们持续打磨构造了更加灵活兼容的分布式多模架构&#xff0c;实现了海量异构数据高性能、低成本的集中管理… …这些底层特性都在为后续提供更…

初见DP

线性DP 例题1 1143. 最长公共子序列 &#xff08;LCS&#xff09; 子序列不连续 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新的字符串&#x…