Linux源码阅读笔记04-实时调度类及SMP和NUMA

简介: Linux源码阅读笔记04-实时调度类及SMP和NUMA

Linux进程分类

  • 实时进程
  • 普通进程
  • 如果系统中有一个实时进程并且可执行,调度器总是会选择他,除非有另外一个优先级高的实时进程。
  • SCHED_FIFO:没有时间片,被调度器选择之后,可以运行任意长的时间。
  • SCHED_RR:有时间片,进程运行时会减少。

实时调度类分析

实时调度实体sched_rt_entity数据结构

struct sched_rt_entity {
  struct list_head    run_list; // 专门用于加入到优先级队列当中
  unsigned long     timeout; // 设置时间超时
  unsigned long     watchdog_stamp; // 记录jiffies值
  unsigned int      time_slice; // 时间片
  unsigned short      on_rq;
  unsigned short      on_list;
  struct sched_rt_entity    *back;
#ifdef CONFIG_RT_GROUP_SCHED
  struct sched_rt_entity    *parent; // 指向父RT调度实体
  /* rq on which this entity is (to be) queued: */
    // 实时类
  struct rt_rq      *rt_rq; // RT调度实体所属的实时运行队列
  /* rq "owned" by this entity/group: */
  struct rt_rq      *my_q; // RT调度实体所拥有的实时运行队列,用于管理子任务或子组任务
#endif
} __randomize_layout;
  • 实时类
struct rt_rq {
  struct rt_prio_array  active;
  unsigned int    rt_nr_running;
  unsigned int    rr_nr_running;
#if defined CONFIG_SMP || defined CONFIG_RT_GROUP_SCHED
  struct {
    int   curr; /* highest queued rt task prio */
#ifdef CONFIG_SMP
    int   next; /* next highest */
#endif
  } highest_prio;
#endif
#ifdef CONFIG_SMP
  unsigned long   rt_nr_migratory;
  unsigned long   rt_nr_total;
  int     overloaded;
  struct plist_head pushable_tasks;
#endif /* CONFIG_SMP */
  int     rt_queued;
  int     rt_throttled;
  u64     rt_time;
  u64     rt_runtime;
  /* Nests inside the rq lock: */
  raw_spinlock_t    rt_runtime_lock;
#ifdef CONFIG_RT_GROUP_SCHED
  unsigned long   rt_nr_boosted;
  struct rq   *rq;
  struct task_group *tg;
#endif
};

实时调度类

const struct sched_class rt_sched_class = {
  .next     = &fair_sched_class,
  .enqueue_task   = enqueue_task_rt,// 将一个task加入就绪队列尾部
  .dequeue_task   = dequeue_task_rt,// 将一个task从就绪队列移除
  .yield_task   = yield_task_rt, // 主动放弃执行
  .check_preempt_curr = check_preempt_curr_rt,
  // 选择就绪队列的拿个任务将要被调度,prev是将要被调度出的任务,返回是将要被调度的任务
  .pick_next_task   = pick_next_task_rt,
  //
  .put_prev_task    = put_prev_task_rt,
  .set_next_task          = set_next_task_rt,
#ifdef CONFIG_SMP
  .balance    = balance_rt,
  .select_task_rq   = select_task_rq_rt,
  .set_cpus_allowed       = set_cpus_allowed_common,
  .rq_online              = rq_online_rt,
  .rq_offline             = rq_offline_rt,
  .task_woken   = task_woken_rt,
  .switched_from    = switched_from_rt,
#endif
  .task_tick    = task_tick_rt,
  .get_rr_interval  = get_rr_interval_rt,
  .prio_changed   = prio_changed_rt,
  .switched_to    = switched_to_rt,
  .update_curr    = update_curr_rt,
#ifdef CONFIG_UCLAMP_TASK
  .uclamp_enabled   = 1,
#endif
};
  • 选择进程

  • 插入进程

  • 删除进程

SMP和NUMA

SMP(对称多处理器结构)

对称多处理器结构(symmetrical mulit-processing,SMP),在对称多处理器系统中,所有处理器的地位都是平等的,所有CPU共享全部资源,比如内存,总线,中断及IO系统等等,都具有相同的可访问性,消除结构上的障碍,最大的特点是共享资源。

  • SMP服务器CPU利用率最好的情况下是2-4个CPU,实践证明。
  • 从应用层到架构层,目前商用服务器大体分三类:SMP、NUMA、MPP。
  • NUMA优势:以太物理服务器内集成多CPU,使系统具有较高的事务处理能力。由于远程内存访问有延迟,所以需要尽量减少不同CPU模块之间的交互。所以显然,NUMA架构适合OLTP事务处理环境。
  • SMP优势:当前使用OTLP程序当中,用户访问一个中断数据库,如果采用SMP架构,他的效率比MPP块。

多处理器系统中,内核需要额外考虑几个问题,确保良好调度。

  • CPU符合尽可能公平。
  • 进程与系统重某些处理器的亲核性。

NUMA(非一致内存访问结构)

NUMA是多处理器计算机,系统各个CPU都有本地内存都可以支持超快的访问能力,各个处理器之间用总线链接,支持对其他CPU的本地内存访问(但是访问比自己内存慢一点)。

CPU域初始化

  • 物理属性分类
  • SMT(Simultaneous Multithreading):超线程,在单个物理处理核心上同时执行多个线程来提高并行性和吞吐量。
  • MC(Multi-core):多核心,在同一芯片上集成了多个独立的处理核心,每个核心都可以独立运行任务。
  • SoC(System on Chip):处理器,集成了整个计算机系统功能的芯片,包括处理器、内存、输入输出接口等。它将多个硬件组件集成在一个芯片上,实现高度集成和协作。
  • Linux内核分类
  • CONFIG_SCHED_SMT。
  • CONFIG_SCHED_MC。
  • DIE。
  • Linux内核多CPU的管理是通过bitmap来管理的,并且定义4种状态:possible/present/online/active。具体源码如下:

相关文章
|
2月前
|
Ubuntu Linux Python
Tkinter错误笔记(一):tkinter.Button在linux下出现乱码
在Linux系统中,使用Tkinter库时可能会遇到中文显示乱码的问题,这通常是由于字体支持问题导致的,可以通过更换支持中文的字体来解决。
168 0
Tkinter错误笔记(一):tkinter.Button在linux下出现乱码
|
1月前
|
人工智能 算法 大数据
Linux内核中的调度算法演变:从O(1)到CFS的优化之旅###
本文深入探讨了Linux操作系统内核中进程调度算法的发展历程,聚焦于O(1)调度器向完全公平调度器(CFS)的转变。不同于传统摘要对研究背景、方法、结果和结论的概述,本文创新性地采用“技术演进时间线”的形式,简明扼要地勾勒出这一转变背后的关键技术里程碑,旨在为读者提供一个清晰的历史脉络,引领其深入了解Linux调度机制的革新之路。 ###
|
1月前
|
算法 Linux 定位技术
Linux内核中的进程调度算法解析####
【10月更文挑战第29天】 本文深入剖析了Linux操作系统的心脏——内核中至关重要的组成部分之一,即进程调度机制。不同于传统的摘要概述,我们将通过一段引人入胜的故事线来揭开进程调度算法的神秘面纱,展现其背后的精妙设计与复杂逻辑,让读者仿佛跟随一位虚拟的“进程侦探”,一步步探索Linux如何高效、公平地管理众多进程,确保系统资源的最优分配与利用。 ####
71 4
|
1月前
|
缓存 负载均衡 算法
Linux内核中的进程调度算法解析####
本文深入探讨了Linux操作系统核心组件之一——进程调度器,着重分析了其采用的CFS(完全公平调度器)算法。不同于传统摘要对研究背景、方法、结果和结论的概述,本文摘要将直接揭示CFS算法的核心优势及其在现代多核处理器环境下如何实现高效、公平的资源分配,同时简要提及该算法如何优化系统响应时间和吞吐量,为读者快速构建对Linux进程调度机制的认知框架。 ####
|
28天前
|
缓存 算法 Linux
Linux内核中的调度策略优化分析####
本文深入探讨了Linux操作系统内核中调度策略的工作原理,分析了不同调度算法(如CFS、实时调度)在多核处理器环境下的性能表现,并提出了针对高并发场景下调度策略的优化建议。通过对比测试数据,展示了调度策略调整对于系统响应时间及吞吐量的影响,为系统管理员和开发者提供了性能调优的参考方向。 ####
|
2月前
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
116 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
2月前
|
Linux 开发工具 Docker
各个类linux服务器安装docker教程
各个类linux服务器安装docker教程
73 0
|
4月前
|
资源调度 监控 网络协议
在Linux中,如何进行系统资源调度?
在Linux中,如何进行系统资源调度?
|
4月前
|
监控 Linux 调度
在Linux中,如何进行调度任务?什么是 crontab 并解释 crontab 中的字段?
在Linux中,如何进行调度任务?什么是 crontab 并解释 crontab 中的字段?
|
4月前
|
负载均衡 算法 Linux
在Linux中,LVS的负载调度算法是什么?
在Linux中,LVS的负载调度算法是什么?