LINUX的XEN和KVM到底区别在什么地方?

news2024/11/23 16:44:20

本文调研的是 Completely Fair Scheduler 算法, 它当前是 Linux 中 SCHED_NORMAL(非实时任务) 一类 task 的默认调度器.

实际上, 运行在 Guest OS 中的应用程序线程还受到 Guest OS 的调度, 分时运行在 vCPU 上, 但这不在本文调研范围内. 本文仅调研 vCPU 被如何调度到 pCPU 上.

从软件架构看

从 vCPU - QEMU 线程 - 物理 CPU 对应关系看

通常, 一个 QEMU 进程创建并服务于一个 VM. QEMU 为 VM 分配一个或多个 vCPU, 每个 vCPU 对应于 QEMU 进程内的一个线程.

所有 QEMU 的线程在 Linux 线程调度上与寻常线程无异, 由 CFS 调度器调度.

从 CPU 状态迁移看

KVM 将自己注册为一个 misc 类的设备, 位于 /dev/kvm 上. 当一个 VM 被创建后, 运行在用户态的 QEMU 通过 ioctl 操作代表 VM, vCPU 的相关文件, 实现与 KVM 通信.

当 QEMU 启动/恢复运行一个 VM 时, pCPU 因 QEMU 发起的系统调用, 由用户态陷入到内核态, 再经由 KVM 调用 VM Entry, 进入到 non-root 模式, 恢复 vCPU 的运行.

CFS 算法

(本文参考的 Linux 内核版本为 5.17 )

vruntime 的具体计算

调度周期: 当运行的线程数 ≤ 8 时, 默认的调度时间周期是 48ms. 当多于 8 个线程时, 时间周期 = 6ms * 线程数. CFS 尝试在一个调度周期内运行所有的 task, 防止饥饿.

进程创建时: 若没有设置子进程先运行, 则一般子进程的 vruntime = 父进程的 vruntime + 等价于一个周期的 vruntime 值.

进程唤醒时: vruntime 值会被更新为 ≥ 所有待调度线程中最小的 vruntime. 使用最小 vruntime 还可以保证频繁睡眠的线程优先被调度, 这对于桌面操作系统非常适合, 可减少交互应用的响应延迟.

调度进程时: 将当前进程加入红黑树, 从红黑树摘下最左的节点, 作为下个进程来运行. 过程中有许多规则和特例.

时钟周期中断: 更新当前进程的 vruntime 和实际运行时间. 若超过了调度周期分配的实际运行时间, 会执行 resched_task(*rq). 在单核 CPU 中, 即为设置 CPU need_resched flag; 在 SMP 上需要触发目标 CPU 上的调度器.

虚拟时钟的时间流速:

static inline u64 calc_delta_fair(u64 delta /* 线程真实运行的时间片长 */, struct sched_entity *se)
{
    if (unlikely(se->load.weight != NICE_0_LOAD))
        // NICE_0_LOAD = 1024
        // 大致上 = delta_exec * NICE_0_LOAD / cur->load.weight;
        // 也就是说, 对于 nice = 0 的进程, vruntime 与真实时间流速一致
        delta = __calc_delta(delta, NICE_0_LOAD, &se->load);

    return delta;
}

参考自

  • 计算所云计算课程 PPT - Ch 2.2
  • 韦师兄 PPT 《KVM 虚拟化》
  • Linux 5.17
  • https://www.kernel.org/doc/html/latest/scheduler/sched-design-CFS.html
  • https://developer.ibm.com/tutorials/l-completely-fair-scheduler/
  • https://z.itpub.net/article/detail/4D5A28D92B6F801DF6E4C7F793969996
  • https://blog.csdn.net/XD_hebuters/article/details/79623130
  • https://www.cnblogs.com/tianguiyu/articles/6091378.html
  • https://www.daimajiaoliu.com/daima/60fed6172434c00
  • https://blog.csdn.net/liuxiaowu19911121/article/details/47070111

(免费订阅,永久学习)学习地址: Dpdk/网络协议栈/vpp/OvS/DDos/NFV/虚拟化/高性能专家-学习视频教程-腾讯课堂

更多DPDK相关学习资料有需要的可以自行报名学习,免费订阅,永久学习,或点击这里加qun免费
领取,关注我持续更新哦! !   

Xen Credit 算法

Xen 基本架构

Xen:

  • 一个 VM 被称作 Domain
  • 隔离不同的 Domain, 为它们提供虚拟化的硬件资源

Domain 0:

  • 特殊, 有特权
  • 管理其他 Domain

vCPU:

  • 每个 VM 拥有一个或多个
  • 状态:
  • 运行中
  • 可运行
  • 阻塞 (VM 自己阻塞的)
  • 阻塞 (VCPU 睡眠 或 被 VMM 暂停)

Credit 算法

(注: Credit 2 算法是 2009 年 George Dunlap 对原算法的一个改进, 包含在 Xen 中, 但默认未启用. 本文调研的是原算法. )

Credit 算法代码实现于 xen/common/sched/credit.c.

(本文参考的 Xen 版本为 4.16, 此时最新的 commit 为 0e03ff97def12b121b5313094a76e5db7bb5c93c)

核心数据结构

// 优先级, 枚举值
#define CSCHED_PRI_TS_BOOST      0      /* time-share waking up */
#define CSCHED_PRI_TS_UNDER     -1      /* time-share w/ credits */
#define CSCHED_PRI_TS_OVER      -2      /* time-share w/o credits */
#define CSCHED_PRI_IDLE         -64     /* idle */

struct csched_dom {                     // 意为 C scheduled domain
    struct domain *dom;                 // 原 Domain 指针
    // dom->sched_priv 指回本 struct
    // 它们互相指向

    // 附加的数据字段
    // ...
    uint16_t weight;                    // Weight
    uint16_t cap;                       // CAP
};

struct csched_unit {                    // vCPU 结构
    // ...
    int pri;                            // 优先级
    atomic_t credit;                    // 当前的 credit
};

struct csched_private {                 // 系统范围内所有 vCPU
    // ...
    struct list_head active_sdom;       // 所有活跃的 csched_dom, 是循环链表的表头
    uint32_t weight;
    uint32_t credit;
    int credit_balance;
};

vCPU 调度的核心过程

初始化时, 设置两个计时器:

- `csched_acct`, 每隔 30ms 执行一次 (全局唯一一个, 所在的物理 CPU 称作 the accounting master)
- `csched_tick`, 每隔 10ms 执行一次 (每个物理 CPU 分别设置了一个, 可能并行执行)

// 对每个物理 CPU 初始化
static void init_pdata(struct csched_private *prv, struct csched_pcpu *spc, int cpu)
{
    // ...
    prv->ncpus++;
    // ...
    if ( prv->ncpus == 1 ) // 第一个 CPU 作为 the accounting master
    {
        prv->master = cpu; // 标记为 master
        // 设置计时器, 执行 csched_acct
        init_timer(&prv->master_ticker, csched_acct, prv, cpu);
        set_timer(&prv->master_ticker, NOW() + prv->tslice);
    }
    // ...
    // 设置计时器, 执行 csched_tick
    init_timer(&spc->ticker, csched_tick, (void *)(unsigned long)cpu, cpu);
    set_timer(&spc->ticker, NOW() + MICROSECS(prv->tick_period_us) );
    // ...
}


// 各个物理 CPU 每 10ms 运行一次
static void cf_check csched_tick(void *_cpu)
{
    // ...
    if ( !is_idle_unit(current->sched_unit) )   // 若当前 vCPU 不是 "空转 vCPU"
        csched_unit_acct(prv, cpu);             // 执行 "vCPU 审计"
    csched_runq_sort(prv, cpu);                 // 对 run queue(就绪队列) 排序
    // ...
}


// 所谓的 vCPU 审计
static void csched_unit_acct(struct csched_private *prv, unsigned int cpu)
{
    // ...
    if ( svc->pri == CSCHED_PRI_TS_BOOST )      // 若上次醒来特权级是 BOOST
    {
        svc->pri = CSCHED_PRI_TS_UNDER;         // 降级为 UNDER
        // ...
    }

    // 该 vCPU 的 credit 被消耗了 100
    burn_credits(svc, NOW());

    if ( list_empty(&svc->active_unit_elem) )
    {
        // 若当前 active vCPU 链表为空, 说明所有 vCPU 的 credit 都为负, 则重新计算credit值
        __csched_unit_acct_start(prv, svc);
    }
    else
    {
        // ...
        // 一些迷惑操作, 不明白作用

        if ( new_cpu != cpu )
        {
            // ...
            // 总之发起了一个 CPU 软中断, 将执行 schedule()
            // 软中断在 xen/common/sched/core.c: scheduler_enable() 注册
            // 本物理 CPU 可能将切换到其他 vCPU
            cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ);
        }
    }
}


// 在 the accounting master 上, 每 30ms 执行一次
static void csched_acct(void* dummy)
{
    struct csched_private *prv = dummy;
    // 声明变量...

    // 遍历当前活跃的调度中的 Domain 循环链表
    list_for_each_safe( iter_sdom, next_sdom, &prv->active_sdom )
    {
        sdom = list_entry(iter_sdom, struct csched_dom, active_sdom_elem);
        // sdom 是刚刚被调度器抢占的那个 Domain 的 csched_dom 结构

        // ...
        // ...
        // ...
        // 计算了 weight_left, credit_peak, credit_cap, credit_fair
        // credit_peak: 若 Domain 的所有 vCPU 各自独占一个物理 CPU 时, 等价的 credit 值
        // credit_cap : 根据 CAP 计算, Domain 能获得的 credit 上限
        // credit_fair: 根据 weight 计算, Domain 能获得的 credit

        if ( credit_fair < credit_peak )
        {
            credit_xtra = 1;
        }
        else
        {
            // 出大问题, 调整一些东西...
        }
        // 最后使用 credit_fair 作为 Domain 当前的 credit

        // 现在把 credit 除以 Domain 拥有的 vCPU 数量
        credit_fair = ( credit_fair + ( sdom->active_unit_count - 1 )
                      ) / sdom->active_unit_count;

        // 遍历 Domain 的 vCPU 循环链表
        list_for_each_safe( iter_unit, next_unit, &sdom->active_unit )
        {
            svc = list_entry(iter_unit, struct csched_unit, active_unit_elem);
            // svc 表示一个 vCPU

            // 原子地 += 和 read vCPU 的 credit
            atomic_add(credit_fair, &svc->credit);
            credit = atomic_read(&svc->credit);

            if ( credit < 0 )
            {
                // 超出 credit 配额了, 优先级降到 OVER
                svc->pri = CSCHED_PRI_TS_OVER;

                // 若超出 CAP, 直接靠边停车 (park) ...
                // 若 credit 小于了下界, 置为下界 ...
            }
            else
            {
                // 超出 credit 配额了, 优先级降到 OVER
                svc->pri = CSCHED_PRI_TS_UNDER;

                // vCPU 可能此时因为曾超过 cap 而暂停, 现在 credit > 0, 再次启动...
                // 若 credit 超过了上界, 直接除以 2, 而且停止继续获得 credit...
            }

            //...
        }
    }

    // ...
}

Xen Credit 与 QEMU/KVM 调度算法对比分析

(纸上谈兵一下, 欢迎批评指正)

综合来看, CFS 调度器的成熟程度比 Xen Credit 算法高很多, 兼顾了更多的设计目标 (也多设置了一大堆编译开关 ). 这可能与 Linux 在服务器、嵌入式设备、大型机和超级计算机不同领域多样化的生态有一定关联.

数据结构

Credit 算法的调度主要基于 Weight 和 CAP 实现的三级 vCPU 队列. CFS 算法则基于以 vruntime 为 key 的进程红黑树实现.

公平性, 无饥饿

一般认为, CFS 能提供很好的公平性和可交互性. Xen 不清楚...

虚拟机支持

W. Jiang et al., "CFS Optimizations to KVM Threads on Multi-Core Environment," 2009 15th International Conference on Parallel and Distributed Systems, 2009, pp. 348-354, doi: 10.1109/ICPADS.2009.83.

这篇 2009 年的文章指出, 若在 VM 中运行多线程程序时 (多线程运行在多个 vCPU 上), 当年的 CFS 调度器性能会变得较差. 这是由于 KVM 线程优先级和 vCPU 线程在 pCPU 上的分配机制不够智能导致的, 以及 KVM 缺乏对 VM 中的自旋锁信息的了解.

不过这些问题都已经被改进了...

它们均对 SMP 有较好的支持.

实时性, IO/CPU 密集应用

Credit 算法的 trick 是引入 boost 级别. 但一个 vCPU 进入 BOOST 级别后, pCPU 在 10ms 内不会再被抢占, 这可能会使某些 UI 桌面程序或高实时性程序的响应变得迟缓. 而且, boost 级的 vCPU 是随机分布在系统中, 在不同 CPU 上的分布不一定均匀.

另外, 据官网文档承认, Xen Credit 对于 "重的" 工作负载, 性能很高; 但对于需要低延迟的应用 (e.g. 互联网应用, 音频 ...), 性能不好, 可通过减小时间片大小改善.

CFS 取消了多级队列的概念, 且启用了更细粒度的调度时间片, 相对实时性较好一些.

原文链接:https://www.zhihu.com/question/19844004/answer/2419797473 

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

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

相关文章

WebDAV之葫芦儿·派盘+无聊笔记

无聊笔记 支持webdav方式连接葫芦儿派盘。 无聊笔记是一款深受用户认可的系统工具,随时都可以进行软件的操作,也可以在线进行笔记的记录,系统会进行智能的保存,满足了用户日常中的需求,可以把软件作为备忘录,笔记本,摘抄录等。 无聊笔记是一个功能强大的记录工具,您…

代码随想录算法训练营第四十二天| LeetCode416. 分割等和子集

一、LeetCode416. 分割等和子集 1&#xff1a;题目描述&#xff08;416. 分割等和子集&#xff09; 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集&#xff0c;使得两个子集的元素和相等。 2&#xff1a;解题思路 本题需要使用01背包的…

合作动态 | 方正璞华与日立签订战略合作协议,加快推进数字化管理变革!

2022年10月27日&#xff0c;方正璞华PLM事业部负责人王志起先生与日立方代表正式签订“方正璞华PLM产品销售合作框架协议”。 根据协议&#xff0c;双方将围绕璞华PLM产品推广、客户拓展、全生命周期运营服务等领域&#xff0c;开展多元化、多层级的深度融合合作&#xff0c;共…

HTML制作一个介绍自己家乡的网站——贵阳,排版整洁,内容丰富,主题鲜明

家乡旅游景点网页作业制作 网页代码运用了DIV盒子的使用方法&#xff0c;如盒子的嵌套、浮动、margin、border、background等属性的使用&#xff0c;外部大盒子设定居中&#xff0c;内部左中右布局&#xff0c;下方横向浮动排列&#xff0c;大学学习的前端知识点和布局方式都有…

CV:计算机视觉技最强学习路线之CV简介(传统视觉技术/相关概念)、早期/中期/近期应用领域(偏具体应用)、经典CNN架构(偏具体算法)概述、常用工具/库/框架/产品、环境安装、常用数据集、编程技巧

CV&#xff1a;计算机视觉技最强学习路线之CV简介(传统视觉技术/相关概念)、早期/中期/近期应用领域(偏具体应用)、经典CNN架构(偏具体算法)概述、常用工具/库/框架/产品、环境安装、常用数据集、编程技巧 导读&#xff1a;计算机视觉技最强学习路线&#xff0c;博主花了三个晚…

Class加载过程

文章目录java解释执行热点代码编译类生命周期加载&#xff08;Loading&#xff09;验证&#xff08;Verification&#xff09;准备&#xff08;Preparation&#xff09;解析&#xff08;Resolution&#xff09;初始化&#xff08;Initialization&#xff09;使用&#xff08;Us…

并发编程(三)原子性(2)

【 悲观锁与乐观锁 】&#xff1a; 【悲观锁】&#xff1a; 一定会被别人打断&#xff1b;我必须得上锁。synchronized就是悲观锁。 【乐观锁】&#xff1a; 乐观锁又称之为——无锁、自旋锁、CAS 。 厕所里的人认为不会有其他人来上厕所和我竞争。 【举例解释CAS操作】&a…

SOHO帮客户找新品,如何拿到最优价?要不要选择大型机械类产品?

做外贸&#xff0c;无论是贸易公司还是工厂&#xff0c;又或者是SOHO。都有机会帮助客户采购自己主打产品之外的其他产品&#xff0c;有些人就会问&#xff0c;对于客户咨询的新产品&#xff0c;我们本身没有熟悉的供应商&#xff0c;这个时候要怎么去找到好的供货商&#xff1…

世界技能大赛夺冠背后,亚马逊云科技如何培养云计算技能人才?

云计算相关专业的就业前景如何&#xff1f; 人社部数据显示&#xff0c;到2025年我国云计算人才缺口将高达近150万。另一方面&#xff0c;根据艾瑞咨询《中国云计算行业洞察与人才分析》报告&#xff0c;2019年云计算领域人才月均薪酬在1万元以上的占比达93.7%&#xff0c;3万元…

VK3606D抗电机马达干扰直接输出6键触摸芯片,电容式6通道触控检测IC低电平有效,无触摸4秒进入待机模式常用于工控面板/空调/风扇/家电等

VINKA/永嘉微电的VK3606D SOP16是一种具有自动校准功能&#xff0c;低待机电流&#xff0c;抗电压波动等特性的&#xff0c;6按键电容式触摸触控检测IC&#xff0c;适用于温控器&#xff0c;86面板触摸开关&#xff0c;智能家居等抗干扰场所 型号&#xff1a;VK3606D 封装形…

WebGL、GPU硬件加速、GLSL、光栅化

一、介绍 WebGL经常被当成3D API&#xff0c;人们总想“我可以使用WebGL和一些神奇的东西做出炫酷的3D作品”。 事实上WebGL仅仅是一个光栅化引擎&#xff0c;它可以根据你的代码绘制出点&#xff0c;线和三角形。 想要利用WebGL完成更复杂任务&#xff0c;取决于你能否提供合…

CentOS Stream 9 配置静态 IP

系统环境&#xff1a; OS&#xff1a;CentOS Stream 9 CentOS Stream 9 不同于以往版本的 CentOS&#xff0c;没有之前的网络设置相关的命令&#xff0c;如&#xff1a; service network start/restart/status systemctl start/restart/status network设置网卡 IP 的配置文件…

新媒体研究杂志社新媒体研究编辑部新媒体研究杂志2022年第18期目录

本期聚焦 出版学核心期刊自媒体运营状况与其学术影响力关系研究 程海燕;季佳乐; 1-5 理论研究 《新媒体研究》投稿&#xff1a;cnqikantg126.com 网络社群网民情绪感染研究综述 单悦影;祁凯; 6-922 基于CiteSpace的被遗忘权研究综述 徐怡; 10-14 应用研究 …

MCE | RNA 逆转录小提示

Tips 1&#xff1a;防止 RNA 模板的降解毫无疑问&#xff0c;RNA 质量对 cDNA 合成结果会产生重要影响。但 RNA 很脆弱&#xff0c;易于降解。为了保证 RNA 的完整性&#xff0c;我们需要小心又小心&#xff0c;比如在冰上操作&#xff0c;用 RNase-free 的枪头和离心管&#x…

力扣27.移除元素【顺序表】

&#x1f648;个人主页&#xff1a;阿伟t &#x1f449;系列专栏&#xff1a;【C语言–大佬之路】 &#x1f388;今日心语&#xff1a;你所看到的惊艳&#xff0c;都曾被平庸所历练。 前言&#xff1a; 在解题过程中一定要画图进行思考&#xff0c;然后再敲代码。 文章目录移除…

计算属性computed、过滤器定义Vue.filter()

计算属性是为了计算得到一个结果而设计的&#xff1b;放在Vue中computed里面定义&#xff1a;如果我们想在页面上打印一个变量&#xff0c;那就直接“{{变量}}”放在大括号里面&#xff0c;然后变量在data里面定义好初始值&#xff0c;就可以在页面上输出了&#xff0c;比如&am…

策略验证_指标买点分析技法_运用KDJ随机指标选择买点

写在前面&#xff1a; 1. 本文中提到的“股票策略校验工具”的具体使用操作请查看该博文&#xff1b; 2. 文中知识内容来自书籍《同花顺炒股软件从入门到精通》 3. 本系列文章是用来学习技法&#xff0c;文中所得内容都仅仅只是作为演示功能使用 目录 解说 策略代码 结果 解…

tftp服务配置的详细过程,简单快速

主机端编译的Linux内核影像必须有至少一种方式下载到目标板上执行。通常是目标板的引导程序负责把主机端的影像文件下载到内存中。根据不同的连接方式&#xff0c;可以有多种文件传输方式&#xff0c;每一种方式都需要相应的传输软件和协议。 在linux开发中最常用的传输方式为网…

打破汽车零部件企业供应链壁垒,数商云SCM供应链系统实现一体化采购协同

随着疫情反复&#xff0c;包括芯片在内的关键零部件短缺&#xff0c;以及原材料成本和物流费用飙升&#xff0c;使得零部件企业利润大幅压缩甚至亏损。当前&#xff0c;在亚洲、欧洲、北美等地&#xff0c;国际零部件厂商正迎来一波“破产潮”&#xff0c;汽车零部件企业举步维…

数据结构(4)树形结构——二叉树(概述、前序、中序、后序、层序遍历JAVA实现)

目录 4.1.树 4.2.二叉树 4.2.1.概述 4.2.3.存储结构 4.2.3.遍历 1.逻辑简介 2.代码示例 4.1.树 树&#xff0c;由n(n≥0)个有限节点和边组成一个具有层次关系的数据结构。树需要满足以下条件&#xff1a; 任何结点的子节点不相交。任何子结点只有一个父节点。N个结点&am…