Merge branch 'main' of github.com:LearningOS/rust-based-os-comp2022 into main

This commit is contained in:
Yu Chen
2022-07-17 09:49:10 +08:00

View File

@@ -32,20 +32,20 @@ ch3 中我们实现的调度算法十分简单。现在我们要为我们的 os
算法描述如下:
(1) 为每个进程设置一个当前 stride,表示该进程当前已经运行的“长度”。另外设置其对应的 pass
值(只与进程的优先权有关系),表示对应进程在调度后,stride 需要进行的累加值。
(1) 为每个进程设置一个当前 pass,表示该进程当前已经运行的“长度”。另外设置其对应的 stride
值(只与进程的优先权有关系),表示对应进程在调度后,pass 需要进行的累加值。
(2) 每次需要调度时,从当前 runnable 态的进程中选择 stride 最小的进程调度。对于获得调度的进程 P将对应的 stride 加上其对应的步长 pass
(2) 每次需要调度时,从当前 runnable 态的进程中选择 pass 最小的进程调度。对于获得调度的进程 P将对应的 pass 加上其对应的步长 stride
(3) 一个时间片后,回到上一步骤,重新调度当前 stride 最小的进程。
(3) 一个时间片后,回到上一步骤,重新调度当前 pass 最小的进程。
可以证明,如果令 P.pass = BigStride / P.priority 其中 P.priority 表示进程的优先权(大于 1
可以证明,如果令 P.stride = BigStride / P.priority 其中 P.priority 表示进程的优先权(大于 1
BigStride 表示一个预先定义的大常数,则该调度方案为每个进程分配的时间将与其优先级成正比。证明过程我们在这里略去,有兴趣的同学可以在网上查找相关资料。
其他实验细节:
- stride 调度要求进程优先级 :math:`\geq 2`,所以设定进程优先级 :math:`\leq 1` 会导致错误。
- 进程初始 stride 设置为 0 即可。
- 进程初始 pass 设置为 0 即可。
- 进程初始优先级设置为 16。
为了实现该调度算法,内核还要增加 set_prio 系统调用
@@ -62,7 +62,7 @@ BigStride 表示一个预先定义的大常数,则该调度方案为每个进
- 你可以在TCB加入新的字段来支持优先级等。
- 为了减少整数除的误差BIG_STRIDE 一般需要很大,但为了不至于发生反转现象(详见问答作业),或许选择一个适中的数即可,当然能进行溢出处理就更好了。
- stride 算法要找到 stride 最小的进程,使用优先级队列是效率不错的办法,但是我们的实验测例很简单,所以效率完全不是问题。事实上,很推荐使用暴力扫一遍的办法找最小值。
- stride 算法要找到 pass 最小的进程,使用优先级队列是效率不错的办法,但是我们的实验测例很简单,所以效率完全不是问题。事实上,很推荐使用暴力扫一遍的办法找最小值。
- 注意设置进程的初始优先级。
.. attention::
@@ -152,38 +152,38 @@ BigStride 表示一个预先定义的大常数,则该调度方案为每个进
stride 算法深入
stride 算法原理非常简单,但是有一个比较大的问题。例如两个 pass = 10 的进程,使用 8bit 无符号整形储存
stride p1.stride = 255, p2.stride = 250在 p2 执行一个时间片后,理论上下一次应该 p1 执行。
stride 算法原理非常简单,但是有一个比较大的问题。例如两个 stride = 10 的进程,使用 8bit 无符号整形储存
pass p1.pass = 255, p2.pass = 250在 p2 执行一个时间片后,理论上下一次应该 p1 执行。
- 实际情况是轮到 p1 执行吗?为什么?
我们之前要求进程优先级 >= 2 其实就是为了解决这个问题。可以证明, **在不考虑溢出的情况下** , 在进程优先级全部 >= 2
的情况下,如果严格按照算法执行,那么 STRIDE_MAX STRIDE_MIN <= BigStride / 2。
的情况下,如果严格按照算法执行,那么 PASS_MAX PASS_MIN <= BigStride / 2。
- 为什么?尝试简单说明(不要求严格证明)。
- 已知以上结论,**考虑溢出的情况下**,可以为 Stride 设计特别的比较器,让 BinaryHeap<Stride> 的 pop
方法能返回真正最小的 Stride。补全下列代码中的 ``partial_cmp`` 函数,假设两个 Stride 永远不会相等。
- 已知以上结论,**考虑溢出的情况下**,可以为 pass 设计特别的比较器,让 BinaryHeap<Pass> 的 pop
方法能返回真正最小的 Pass。补全下列代码中的 ``partial_cmp`` 函数,假设两个 Pass 永远不会相等。
.. code-block:: rust
use core::cmp::Ordering;
struct Stride(u64);
struct Pass(u64);
impl PartialOrd for Stride {
impl PartialOrd for Pass {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
// ...
}
}
impl PartialEq for Stride {
impl PartialEq for Pass {
fn eq(&self, other: &Self) -> bool {
false
}
}
TIPS: 使用 8 bits 存储 stride, BigStride = 255, 则: ``(125 < 255) == false``, ``(129 < 255) == true``.
TIPS: 使用 8 bits 存储 pass, BigStride = 255, 则: ``(125 < 255) == false``, ``(129 < 255) == true``.
报告要求
------------------------------------------------------------