mirror of
https://github.com/LearningOS/rust-based-os-comp2022.git
synced 2026-05-05 20:59:48 +08:00
deploy: 2d56268908
This commit is contained in:
@@ -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``.
|
||||
|
||||
报告要求
|
||||
------------------------------------------------------------
|
||||
|
||||
@@ -319,18 +319,18 @@
|
||||
<h3>stride 调度算法<a class="headerlink" href="#stride" title="永久链接至标题">¶</a></h3>
|
||||
<p>ch3 中我们实现的调度算法十分简单。现在我们要为我们的 os 实现一种带优先级的调度算法:stride 调度算法。</p>
|
||||
<p>算法描述如下:</p>
|
||||
<p>(1) 为每个进程设置一个当前 stride,表示该进程当前已经运行的“长度”。另外设置其对应的 pass
|
||||
值(只与进程的优先权有关系),表示对应进程在调度后,stride 需要进行的累加值。</p>
|
||||
<p>(1) 为每个进程设置一个当前 pass,表示该进程当前已经运行的“长度”。另外设置其对应的 stride
|
||||
值(只与进程的优先权有关系),表示对应进程在调度后,pass 需要进行的累加值。</p>
|
||||
<ol class="arabic simple" start="2">
|
||||
<li><p>每次需要调度时,从当前 runnable 态的进程中选择 stride 最小的进程调度。对于获得调度的进程 P,将对应的 stride 加上其对应的步长 pass。</p></li>
|
||||
<li><p>一个时间片后,回到上一步骤,重新调度当前 stride 最小的进程。</p></li>
|
||||
<li><p>每次需要调度时,从当前 runnable 态的进程中选择 pass 最小的进程调度。对于获得调度的进程 P,将对应的 pass 加上其对应的步长 stride。</p></li>
|
||||
<li><p>一个时间片后,回到上一步骤,重新调度当前 pass 最小的进程。</p></li>
|
||||
</ol>
|
||||
<p>可以证明,如果令 P.pass = BigStride / P.priority 其中 P.priority 表示进程的优先权(大于 1),而
|
||||
<p>可以证明,如果令 P.stride = BigStride / P.priority 其中 P.priority 表示进程的优先权(大于 1),而
|
||||
BigStride 表示一个预先定义的大常数,则该调度方案为每个进程分配的时间将与其优先级成正比。证明过程我们在这里略去,有兴趣的同学可以在网上查找相关资料。</p>
|
||||
<p>其他实验细节:</p>
|
||||
<ul class="simple">
|
||||
<li><p>stride 调度要求进程优先级 <span class="math notranslate nohighlight">\(\geq 2\)</span>,所以设定进程优先级 <span class="math notranslate nohighlight">\(\leq 1\)</span> 会导致错误。</p></li>
|
||||
<li><p>进程初始 stride 设置为 0 即可。</p></li>
|
||||
<li><p>进程初始 pass 设置为 0 即可。</p></li>
|
||||
<li><p>进程初始优先级设置为 16。</p></li>
|
||||
</ul>
|
||||
<p>为了实现该调度算法,内核还要增加 set_prio 系统调用</p>
|
||||
@@ -345,7 +345,7 @@ BigStride 表示一个预先定义的大常数,则该调度方案为每个进
|
||||
<ul class="simple">
|
||||
<li><p>你可以在TCB加入新的字段来支持优先级等。</p></li>
|
||||
<li><p>为了减少整数除的误差,BIG_STRIDE 一般需要很大,但为了不至于发生反转现象(详见问答作业),或许选择一个适中的数即可,当然能进行溢出处理就更好了。</p></li>
|
||||
<li><p>stride 算法要找到 stride 最小的进程,使用优先级队列是效率不错的办法,但是我们的实验测例很简单,所以效率完全不是问题。事实上,很推荐使用暴力扫一遍的办法找最小值。</p></li>
|
||||
<li><p>stride 算法要找到 pass 最小的进程,使用优先级队列是效率不错的办法,但是我们的实验测例很简单,所以效率完全不是问题。事实上,很推荐使用暴力扫一遍的办法找最小值。</p></li>
|
||||
<li><p>注意设置进程的初始优先级。</p></li>
|
||||
</ul>
|
||||
<div class="admonition attention">
|
||||
@@ -434,36 +434,36 @@ BigStride 表示一个预先定义的大常数,则该调度方案为每个进
|
||||
<h2>问答作业<a class="headerlink" href="#id3" title="永久链接至标题">¶</a></h2>
|
||||
<p>stride 算法深入</p>
|
||||
<blockquote>
|
||||
<div><p>stride 算法原理非常简单,但是有一个比较大的问题。例如两个 pass = 10 的进程,使用 8bit 无符号整形储存
|
||||
stride, p1.stride = 255, p2.stride = 250,在 p2 执行一个时间片后,理论上下一次应该 p1 执行。</p>
|
||||
<div><p>stride 算法原理非常简单,但是有一个比较大的问题。例如两个 stride = 10 的进程,使用 8bit 无符号整形储存
|
||||
pass, p1.pass = 255, p2.pass = 250,在 p2 执行一个时间片后,理论上下一次应该 p1 执行。</p>
|
||||
<ul class="simple">
|
||||
<li><p>实际情况是轮到 p1 执行吗?为什么?</p></li>
|
||||
</ul>
|
||||
<p>我们之前要求进程优先级 >= 2 其实就是为了解决这个问题。可以证明, <strong>在不考虑溢出的情况下</strong> , 在进程优先级全部 >= 2
|
||||
的情况下,如果严格按照算法执行,那么 STRIDE_MAX – STRIDE_MIN <= BigStride / 2。</p>
|
||||
的情况下,如果严格按照算法执行,那么 PASS_MAX – PASS_MIN <= BigStride / 2。</p>
|
||||
<ul class="simple">
|
||||
<li><p>为什么?尝试简单说明(不要求严格证明)。</p></li>
|
||||
<li><p>已知以上结论,<strong>考虑溢出的情况下</strong>,可以为 Stride 设计特别的比较器,让 BinaryHeap<Stride> 的 pop
|
||||
方法能返回真正最小的 Stride。补全下列代码中的 <code class="docutils literal notranslate"><span class="pre">partial_cmp</span></code> 函数,假设两个 Stride 永远不会相等。</p></li>
|
||||
<li><p>已知以上结论,<strong>考虑溢出的情况下</strong>,可以为 pass 设计特别的比较器,让 BinaryHeap<Pass> 的 pop
|
||||
方法能返回真正最小的 Pass。补全下列代码中的 <code class="docutils literal notranslate"><span class="pre">partial_cmp</span></code> 函数,假设两个 Pass 永远不会相等。</p></li>
|
||||
</ul>
|
||||
<div class="highlight-rust notranslate"><div class="highlight"><pre><span></span><span class="k">use</span><span class="w"> </span><span class="n">core</span>::<span class="n">cmp</span>::<span class="n">Ordering</span><span class="p">;</span><span class="w"></span>
|
||||
|
||||
<span class="k">struct</span> <span class="nc">Stride</span><span class="p">(</span><span class="kt">u64</span><span class="p">);</span><span class="w"></span>
|
||||
<span class="k">struct</span> <span class="nc">Pass</span><span class="p">(</span><span class="kt">u64</span><span class="p">);</span><span class="w"></span>
|
||||
|
||||
<span class="k">impl</span><span class="w"> </span><span class="nb">PartialOrd</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">Stride</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
|
||||
<span class="k">impl</span><span class="w"> </span><span class="nb">PartialOrd</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">Pass</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="k">fn</span> <span class="nf">partial_cmp</span><span class="p">(</span><span class="o">&</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">other</span>: <span class="kp">&</span><span class="nc">Self</span><span class="p">)</span><span class="w"> </span>-> <span class="nb">Option</span><span class="o"><</span><span class="n">Ordering</span><span class="o">></span><span class="w"> </span><span class="p">{</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="c1">// ...</span>
|
||||
<span class="w"> </span><span class="p">}</span><span class="w"></span>
|
||||
<span class="p">}</span><span class="w"></span>
|
||||
|
||||
<span class="k">impl</span><span class="w"> </span><span class="nb">PartialEq</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">Stride</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
|
||||
<span class="k">impl</span><span class="w"> </span><span class="nb">PartialEq</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">Pass</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="k">fn</span> <span class="nf">eq</span><span class="p">(</span><span class="o">&</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">other</span>: <span class="kp">&</span><span class="nc">Self</span><span class="p">)</span><span class="w"> </span>-> <span class="kt">bool</span> <span class="p">{</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="kc">false</span><span class="w"></span>
|
||||
<span class="w"> </span><span class="p">}</span><span class="w"></span>
|
||||
<span class="p">}</span><span class="w"></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>TIPS: 使用 8 bits 存储 stride, BigStride = 255, 则: <code class="docutils literal notranslate"><span class="pre">(125</span> <span class="pre"><</span> <span class="pre">255)</span> <span class="pre">==</span> <span class="pre">false</span></code>, <code class="docutils literal notranslate"><span class="pre">(129</span> <span class="pre"><</span> <span class="pre">255)</span> <span class="pre">==</span> <span class="pre">true</span></code>.</p>
|
||||
<p>TIPS: 使用 8 bits 存储 pass, BigStride = 255, 则: <code class="docutils literal notranslate"><span class="pre">(125</span> <span class="pre"><</span> <span class="pre">255)</span> <span class="pre">==</span> <span class="pre">false</span></code>, <code class="docutils literal notranslate"><span class="pre">(129</span> <span class="pre"><</span> <span class="pre">255)</span> <span class="pre">==</span> <span class="pre">true</span></code>.</p>
|
||||
</div></blockquote>
|
||||
</div>
|
||||
<div class="section" id="id4">
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user