-
CPU如何读写数据
-
整个存储层次
-
CPU 访问 L1 Cache 速度比访问内存快 100 倍,这就是为什么 CPU 里会有 L1~L3 Cache 的原因,目的就是把 Cache 作为 CPU 与内存之间的缓存层,以减少对内存的访问频率。
-
-
CPU 从内存中读取数据到 Cache 的时候,并不是一个字节一个字节读取,而是一块一块的方式来读取数据的,这一块一块的数据被称为 CPU Cache Line(缓存块) CPU Cache Line 是 CPU 从内存读取数据到 Cache 的单位。
-
cache伪共享
- 避免伪共享的方法
-
对于多个线程共享的热点数据,即经常会修改的数据,应该避免这些数据刚好在同一个 Cache Line 中,否则就会出现为伪共享的问题。
-
因此,针对在同一个 Cache Line 中的共享的数据,如果在多核之间竞争比较严重,为了防止伪共享现象的发生,可以采用上面的宏定义使得变量在 Cache Line 里是对齐的。
-
- 避免伪共享的方法
-
-
CPU如何选择线程的
-
在 Linux 内核中,进程和线程都是用
task_struct
结构体表示的,区别在于线程的 task_struct 结构体里部分资源是共享了进程已创建的资源 -
一般来说,没有创建线程的进程,是只有单个执行流,它被称为是主线程。如果想让进程处理更多的事情,可以创建多个线程分别去处理,但不管怎么样,它们对应到内核里都是
task_struct
。 -
Linux 内核里的调度器,调度的对象就是
task_struct
,接下来我们就把这个数据结构统称为任务。 -
在 Linux 系统中,根据任务的优先级以及响应要求,主要分为两种,其中优先级的数值越小,优先级越高:
-
实时任务,对系统的响应时间要求很高,也就是要尽可能快的执行实时任务,优先级在
0~99
范围内的就算实时任务; -
普通任务,响应时间没有很高的要求,优先级在
100~139
范围内都是普通任务级别
-
-
-
调度类
-
Deadline 和 Realtime 这两个调度类,都是应用于实时任务的,这两个调度类的调度策略合起来共有这三种,它们的作用如下
-
SCHED_DEADLINE:是按照 deadline 进行调度的,距离当前时间点最近的 deadline 的任务会被优先调度;
-
SCHED_FIFO:对于相同优先级的任务,按先来先服务的原则,但是优先级更高的任务,可以抢占低优先级的任务,也就是优先级高的可以「插队」;
-
SCHED_RR:对于相同优先级的任务,轮流着运行,每个任务都有一定的时间片,当用完时间片的任务会被放到队列尾部,以保证相同优先级任务的公平性,但是高优先级的任务依然可以抢占低优先级的任务;
-
-
Fair 调度类是应用于普通任务,都是由 CFS 调度器管理的,分为两种调度策略
-
SCHED_NORMAL:普通任务使用的调度策略;
-
SCHED_BATCH:后台任务的调度策略,不和终端进行交互,因此在不影响其他需要交互的任务,可以适当降低它的优先级
-
-
-
完全公平调度(Completely Fair Scheduling)
-
这个算法的理念是想让分配给每个任务的 CPU 时间是一样,于是它为每个任务安排一个虚拟运行时间 vruntime,如果一个任务在运行,其运行的越久,该任务的 vruntime 自然就会越大,而没有被运行的任务,vruntime 是不会变化的。
-
在 CFS 算法调度的时候,会优先选择 vruntime 少的任务,以保证每个任务的公平性。
-
在计算虚拟运行时间 vruntime 还要考虑普通任务的权重值,注意权重值并不是优先级的值,内核中会有一个 nice 级别与权重值的转换表,nice 级别越低的权重值就越大
-
-
CPU运行队列
-
一个系统通常都会运行着很多任务,多任务的数量基本都是远超 CPU 核心数量,因此这时候就需要排队。
-
每个 CPU 都有自己的运行队列(Run Queue, rq),用于描述在此 CPU 上所运行的所有进程,其队列包含三个运行队列,Deadline 运行队列 dl_rq、实时任务运行队列 rt_rq 和 CFS 运行队列 cfs_rq,其中 cfs_rq 是用红黑树来描述的,按 vruntime 大小来排序的,最左侧的叶子节点,就是下次会被调度的任务。
-
这几种调度类是有优先级的,优先级如下:Deadline > Realtime > Fair,这意味着 Linux 选择下一个任务执行的时候,会按照此优先级顺序进行选择,也就是说先从
dl_rq
里选择任务,然后从rt_rq
里选择任务,最后从cfs_rq
里选择任务。因此,实时任务总是会比普通任务优先被执行
-
-
-
调整优先级
-
如果我们启动任务的时候,没有特意去指定优先级的话,默认情况下都是普通任务,普通任务的调度类是 Fair,由 CFS 调度器来进行管理。CFS 调度器的目的是实现任务运行的公平性,也就是保障每个任务的运行的时间是差不多的。
-
如果你想让某个普通任务有更多的执行时间,可以调整任务的
nice
值,从而让优先级高一些的任务执行更多时间。nice 的值能设置的范围是-20~19
, 值越低,表明优先级越高,因此 -20 是最高优先级,19 则是最低优先级,默认优先级是 0。 -
nice 值并不是表示优先级,而是表示优先级的修正数值,它与优先级(priority)的关系是这样的:priority(new) = priority(old) + nice。内核中,priority 的范围是 0~139,值越低,优先级越高,其中前面的 0~99 范围是提供给实时任务使用的,而 nice 值是映射到 100~139,这个范围是提供给普通任务用的,因此 nice 值调整的是普通任务的优先级。
-
nice 调整的是普通任务的优先级,所以不管怎么缩小 nice 值,任务永远都是普通任务,如果某些任务要求实时性比较高,那么你可以考虑改变任务的优先级以及调度策略,使得它变成实时任务
-
CPU执行过程
最新推荐文章于 2024-08-24 20:40:44 发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)