応用情報技術者 2016年 秋期 午前2 問18
問題文
プログラムで使用可能な実メモリ枠が3ページである仮想記憶システムにおいて、大きさ6 ページのプログラムが実行されたとき、ページフォールトは何回発生するか。ここで、プログラム実行時のページ読込み順序は、0, 1,2,3,4,0,2,4,3,1,4,5とする。ページング方式は、LRU (Least Recently Used)とし、初期状態では、実メモリにはいずれのページも読み込まれていないものとする。
選択肢
ア:9
イ:10(正解)
ウ:11
エ:12
🔒 解説は解答すると表示されます
LRUページ置換【午前2解説】
正解の理由
与えられた参照列(0, 1, 2, 3, 4, 0, 2, 4, 3, 1, 4, 5)を、実メモリ枠3ページ・LRU置換で逐次シミュレーションすると、ページが参照されて実メモリに存在しないときにのみページフォールトが発生します。逐次シミュレーションの結果、ページフォールトは合計で10回発生するため、正答は イ(10回)となります。
解法ステップ
- 初期状態は空の3フレームとする。
- 参照ページを先頭から順に処理する。
- 参照ページが既に実メモリにあればヒット:ページフォールトは起きない。該当ページを「最も最近使用された」扱いに更新する。
- 実メモリになければページフォールト:空きフレームがあれば読み込む。空きがなければ「最も最近使われていない(LRU)」ページを追い出して新しいページを読み込む。読み込みはページフォールト1回としてカウントする。
- 各参照ごとにフレームの中身とLRUで追い出されるページを明示し、ページフォールトの有無を判定する。
- 全参照を終えたときのページフォールト総数が解。
以下に、参照ごとの実メモリの状態(フレームの中身)と、フォールト判定・追い出し理由を示す。
参照列の逐次シミュレーション(詳細)
参照列: 0, 1, 2, 3, 4, 0, 2, 4, 3, 1, 4, 5
合計ページフォールト回数 = 10回。
(表の「F回目」は累計フォールト数。LRU判定は、直近の参照時刻が最も古いページを追い出すという方針に基づく)
選択肢別の誤答解説
- ア: 9
- 1回分足りない数になっている場合、どこかの参照をヒットと誤認している可能性が高いです。本問では特にステップ9または12での置換を見落とすミスが起きやすいです。
- イ: 10
- 正解。上の逐次表で示したように合計10回のフォールトとなります。
- ウ: 11
- 1回多い数を選ぶ誤りは、ヒットの参照(ステップ8や11)を誤ってフォールト扱いにしてしまったことが原因です。ヒット時は置換もフォールトも起こらない点を忘れがちです。
- エ: 12
- すべての参照でフォールトが起きると仮定した誤りです。初期の空フレームを考慮しても最大で12とは限らず、ヒット発生箇所(本問ではステップ8と11)が存在するため過大評価になります。
よくある誤解
- LRUを使うのに「最初に入ったページを追い出す(FIFO)」と混同する。LRUは「最も長い間参照されていない」ページを追い出す点が異なります。
- ヒット時にページの「使用時刻(最近使用)」を更新しないまま処理を進めてしまい、次の置換判定で誤ったページを追い出す。特に本問のステップ8・11のヒット後の更新を忘れると誤答につながる。
- 初期フレームを全て空としない、または初期ロード時のフォールト数を適切にカウントしない(最初に読み込むページは各々フォールトとして数える)点。
補足コラム
- LRUの実装方法
- スタック(または双方向連結リスト)で参照ごとにページを先頭に移動し、末尾を追い出す方法(O(1)に近い操作が可能)。
- ハッシュ+double-linked listで高速化する実装が一般的(OSやキャッシュの実装で用いられる)。
- ハードウェア支援がない場合、完全なLRUはコストが高いため CLOCK(近似LRU)などが用いられることがある。
- 試験での省力化テクニック
- 小さなフレーム数・参照列なら手で逐次シミュレーションするのが確実。フレームの中身と「直近使用順(MRU→…→LRU)」を簡潔にメモすることでミスを減らせます。
簡単なシミュレーション用サンプル(参考)
def lru_faults(refs, frames):
mem = []
faults = 0
# mem を MRU->...->LRU の順で保持
for p in refs:
if p in mem:
# ヒット:p を先頭(MRU)に移動
mem.remove(p)
mem.insert(0, p)
else:
# フォールト
faults += 1
if len(mem) < frames:
mem.insert(0, p)
else:
# LRU は末尾を削除
mem.pop()
mem.insert(0, p)
return faults
print(lru_faults([0,1,2,3,4,0,2,4,3,1,4,5], 3)) # -> 10
FAQ
Q. 参照列に同じページが連続して現れた場合は?
A. 2回目以降はヒットになり、LRUの更新だけ行う(フォールトは発生しない)。ヒット時に必ず「最近使用」の位置を更新すること。
A. 2回目以降はヒットになり、LRUの更新だけ行う(フォールトは発生しない)。ヒット時に必ず「最近使用」の位置を更新すること。
Q. フレーム数を増やすとフォールト回数は常に減るか?
A. 原則としては減ることが多いですが、特定の置換アルゴリズムや参照列によっては一時的に挙動の差異(Beladyの異常など)が生じることがあります。LRU自体はフレーム増加でフォールトは非増加となる性質を持ちます。
A. 原則としては減ることが多いですが、特定の置換アルゴリズムや参照列によっては一時的に挙動の差異(Beladyの異常など)が生じることがあります。LRU自体はフレーム増加でフォールトは非増加となる性質を持ちます。
関連キーワード: LRU、ページフォールト、仮想記憶、ページ置換、LRUシミュレーション、CLOCK、ページ参照列

\ せっかくなら /
応用情報技術者を
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

