<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ソフトウェア | 基本情報技術者試験 受験ナビ｜科目A・科目B対策から過去問解説まで 250本以上の記事を掲載</title>
	<atom:link href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/tag/%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.seplus.jp/dokushuzemi/ec/fe/fenavi</link>
	<description>基本情報技術者試験を学習する人のためにつくられた専門メディア。250本以上の記事を掲載し、勉強方法や各分野のポイント、過去問解説など、試験に役立つ情報を発信。試験対策書籍を執筆する著者が、はじめて学ぶ人でもわかりやすく解説します。（2023年度からの新制度に対応済み）</description>
	<lastBuildDate>Tue, 21 Jul 2026 09:45:11 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.9.29</generator>
	<item>
		<title>基本情報でわかる コンパイラ 最適化</title>
		<link>https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/mastering_tech/compiler_optimization/</link>
		<pubDate>Mon, 15 Feb 2021 06:44:19 +0000</pubDate>
		<dc:creator><![CDATA[矢沢 久雄]]></dc:creator>
				<category><![CDATA[ソフトウェア]]></category>
		<category><![CDATA[午前問題と午後問題の違い]]></category>
		<category><![CDATA[情報落ち]]></category>

		<guid isPermaLink="false">https://www.seplus.jp/dokushuzemi/fe/fenavi/?post_type=mastering_tech&#038;p=5115</guid>
		<description><![CDATA[<p>この連載では、基本情報技術者試験によく出題されるテクノロジー関連の用語を、午前問題と午後問題のセットを使って解説します。 午前問題で用語の意味や概念を知り、午後問題で技術の活用方法を知ってください。それによって、単なる丸 [&#8230;]</p>
<p>The post <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/mastering_tech/compiler_optimization/">基本情報でわかる コンパイラ 最適化</a> first appeared on <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi">基本情報技術者試験 受験ナビ｜科目A・科目B対策から過去問解説まで 250本以上の記事を掲載</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>この連載では、基本情報技術者試験によく出題されるテクノロジー関連の用語を、午前問題と午後問題のセットを使って解説します。</p>
<p>午前問題で用語の意味や概念を知り、午後問題で技術の活用方法を知ってください。それによって、単なる丸暗記では得られない明確さで、用語を理解できるようになります。</p>
<p>今回のテーマは、 <span class="bold">コンパイラの最適化</span> です。</p>
<style>pre{font-family:'consolas','Courier New',"HCo Gotham SSm",Gotham,"ヒラギノ角ゴ Pro W3","Hiragino Kaku Gothic ProN","Hiragino Sans","BIZ UDPGothic",Meiryo,sans-serif!important;background:#292a33;color:#eceff1;font-size:1em;line-height:1.8;margin:1.5em auto;margin:1em -7.5%;padding:1em 7.5%}code{font-family:'consolas','Courier New',"HCo Gotham SSm",Gotham,"ヒラギノ角ゴ Pro W3","Hiragino Kaku Gothic ProN","Hiragino Sans","BIZ UDPGothic",Meiryo,sans-serif!important;background:#292a33;color:#eceff1;font-size:1em;line-height:1.8;padding:.25em;margin:auto.5em;border-radius:.25em;}.commentout{color:#797c93;}dl.inline dd{margin-left:3.5em;}th{text-align:center;}</style>
<div class="pad_20 grey lighten-5 blue-grey-text hide-on-med-and-up c-round mag_h40 small-text">
<i class="material-icons light-blue-text mag_rt05">info</i>編集部注: スマートフォンでご覧の際は、アルゴリズムを横スクロールすると全文をご覧になれます
</div>
<h2>コンパイラの最適化とは？</h2>
<p>プログラムを実行する方式には、大きく分けて <span class="u">インタプリタ</span> と <span class="u">コンパイラ</span> があります。</p>
<p>インタプリタは、プログラムの内容を 1 行ずつマシン語（コンピュータが直接理解できる命令）に逐次変換しながら逐次実行します。</p>
<p>コンパイラは、プログラムのすべての内容をマシン語に一括変換してから一括実行します。</p>
<p>&nbsp;</p>
<p>インタプリタとコンパイラには、それぞれ長所と短所がありますが、今回のテーマである「最適化（ optimization ）」は、コンパイラの長所です。</p>
<p>最適化とは、プログラムをマシン語に一括変換するときに、プログラムの中にある無駄を排除することです。これによって、プログラムの実行速度を向上させたり、プログラムのサイズを小さくしたりできます。</p>
<p>&nbsp;</p>
<p>たとえば、図 1 に示した 3 行のプログラムがあるとしましょう。ここでは、基本情報技術者試験の擬似言語でプログラムを記述しています。<code>Print</code>は、引数の値を画面に表示する関数だとします。</p>
<figure class="mag_h30"><figcaption>図 1　無駄があるプログラムの例</figcaption><pre>
・A ← 123
・A ← 123
・Print(A)
</pre>
</figure>
<p>このプログラムでは、</p>
<pre>・A ← 123</pre>
<p>という同じ処理（変数 A に 123 という適当な値を代入する処理）が、わざとですが、 2 回記述されています。同じ処理を 2 回記述することは無駄なことなので、コンパイラは、プログラムの内容を図 2 であると解釈して、マシン語に変換します。 <code>・A ← 123</code>という処理を 1 回だけにしていることが最適化です。</p>
<figure class="mag_h30"><figcaption>図 2　無駄を排除したプログラムの例</figcaption><pre>
・A ← 123
・Print(A)
</pre>
</figure>
<p>さらに、コンパイラは、「このプログラムは、画面に 123 を表示できればよいのだから、変数 A を使うことは無駄である」と解釈して、図 3 に示したように最適化します。画面に 123 を表示する<code>・Print(123)</code>という処理だけになりました。</p>
<figure class="mag_h30"><figcaption>図 3　さらに無駄を排除したプログラムの例</figcaption><pre>
・Print(123)
</pre>
</figure>
<p>コンパイラに最適化ができるのは、プログラムのすべての内容を見てからマシン語に変換するからです。すべてを見れば、無駄があることがわかります。</p>
<p>それに対して、<span class="u">インタプリタには、最適化ができません。</span>なぜなら、プログラムの内容を 1 行ずつ見ているので、無駄があることがわからないからです。</p>
<p>たとえば、先ほど図 1 に示した 3 行のプログラムをインタプリタで実行すると、図 4 の (1), (2), (3) の順に、逐次変換されて、逐次実行されます。</p>
<figure class="mag_h30"><figcaption>図 4　無駄があるプログラムをインタプリタで実行した場合</figcaption><pre>
・A ← 123     <span class="commentout">・・・(1) この 1 行をマシン語に変換して実行する</span>
・A ← 123     <span class="commentout">・・・(2) この 1 行をマシン語に変換して実行する</span>
・Print(A)    <span class="commentout">・・・(3) この 1 行をマシン語に変換して実行する</span>
</pre>
</figure>
<h2>コンパイラの最適化 に関する午前問題</h2>
<p>コンパイラの最適化の意味がわかったところで、午前問題を解いてみましょう。以下に問題を示します。</p>
<p>選択肢の中にある「オブジェクトコード」とは、マシン語のことです。「ソースコード」とは、マシン語に変換される前のプログラムのことです。</p>
<div class="card-panel mag_h30">
問 19　平成 28 年度 春期 午前</p>
<p>コンパイラにおける最適化の説明として，適切なものはどれか。</p>
<dl class="inline">
<dt>ア</dt>
<dd>オブジェクトコードを生成する代わりに，インタプリタ用の中間コードを生成する。</dd>
<dt>イ</dt>
<dd>コンパイルを実施するコンピュータとは異なるアーキテクチャをもったコンピュータで動作するオブジェクトコードを生成する。</dd>
<dt>ウ</dt>
<dd>ソースコードを解析して，実行時の処理効率を高めたオブジェクトコードを生成する。</dd>
<dt>エ</dt>
<dd>プログラムの実行時に，呼び出されたサブプログラム名やある時点での変数の内容を表示するようなオブジェクトコードを生成する。</dd>
</dl>
</div>
<blockquote class="grey-text"><p>ソースコードを解析して、実行時の処理効率を高めたオブジェクトコートを生成する</p></blockquote>
<p>と説明している選択肢ウが正解です。</p>
<p>その他の選択肢が何の説明であるかは、気にしないでください。他のツールの説明の場合もありますが、まったくデタラメの場合もあるからです。</p>
<p class="mag_tp20 mag_bt40"><span class="chip mag_rt05">解答</span>ウ</p>
<h2>コンパイラの最適化に関する午後問題（最適化の具体例）</h2>
<p>以下は、コンパイラの最適化に関する午後問題を一部抜粋したものです。</p>
<p>他の記事でも書きましたが「基本情報技術者試験は、実によくできているなあ！」と思います。この問題の前半部では、コンパイラの最適化の様々な具体例を示しています。そして、後半部では、コンパイラの最適化の弊害を示しています。</p>
<p>つまり、<span class="u">コンパイラの最適化は、確かに便利ではあっても、いいことづくめではない、ということを示している</span>のです。この問題によって、コンパイラの最適化を深く理解できます。</p>
<div class="card-panel mag_h30">
問 2　平成 24 年度 春期 午後（一部抜粋）</p>
<p>　コンパイラの最適化に関する次の記述を読んで，設問 1 ～ 3 に答えよ。</p>
<div class="mag_lt10">　コンパイラとは，プログラム言語で記述された原始プログラムを翻訳して目的プログラムを生成するためのソフトウェアである。コンパイラの機能の一つに最適化がある。最適化では，原始プログラムを翻訳する過程で，プログラムの実行時間を短くするために原始プログラムの構造を変換する。最適化の方法の例を表 1 に示す。</div>
<table class="striped mag_h30">
<caption>表 1 最適化の方法の例</caption>
<thead>
<tr>
<th width="30%">最適化の方法</th>
<th width="70%">内容</th>
</tr>
</thead>
<tbody>
<tr>
<td>関数のインライン展開</td>
<td>関数を呼び出す箇所に，呼び出される関数のプログラムを展開する。</td>
</tr>
<tr>
<td>共通部分式の削除</td>
<td>同じ式が複数の箇所に存在し，それらの式で使用している変数の値が変更されず，式の値が変化しないとき，その式の値を作業用変数に格納する文を追加し，複数の同じ式をその作業用変数で置き換える。</td>
</tr>
<tr>
<td>定数の畳込み</td>
<td>プログラム中の定数同士の計算式を，その計算結果で置き換える。</td>
</tr>
<tr>
<td>定数伝播</td>
<td>変数を定数で置き換える。</td>
</tr>
<tr>
<td>無用命令の削除</td>
<td>プログラムの実行結果に影響しない文を削除する。</td>
</tr>
<tr>
<td>ループ内不変式の移動</td>
<td>ループ中で値の変化しない式があるとき，その式をループの外に移動する。</td>
</tr>
<tr>
<td>ループのアンローリング</td>
<td>ループ中の繰返しの処理を展開する。</td>
</tr>
</tbody>
</table>
<p>　擬似言語の形式で記述したプログラムの一部 (以下，プログラム 1 という) に対して，表 1 の最適化の方法を複数組み合わせて最適化した例を，表 2 に示す。</p>
<p>〔プログラム 1 〕</p>
<pre class="mag_w00">
■ i : 0, i ≦ 1, 1
| • x[i] ← y[i] + m + n
| • v[i] ← w[1] + m + n
■
</pre>
<table class="mag_h30 block responsive-width">
<caption>表 2 プログラム 1 の最適化の例</caption>
<thead>
<tr>
<th>最適化の方法</th>
<th>プログラム 1 の変換</th>
</tr>
</thead>
<tbody>
<tr>
<th>(1)</th>
<td>
<pre class="mag_w00">
■ i : 0, i ≦ 1, 1
| ･ t ← m + n
| ･ x[i] ← y[i] + t
| ･ v[i] ← w[i] + t
■
</pre>
</td>
</tr>
<tr>
<th>(2)</th>
<td>
<pre class="mag_w00">･ t ← m + n
■ i : 0, i ≦ 1, 1
| ･ x[1] ← y[1] + t
| ･ v[1] ← w[1] + t
■
</pre>
</td>
</tr>
<tr>
<th>(3)</th>
<td>
<pre class="mag_w00">･ t ← m + n
･ x[0] ← y[0] + t
･ v[0] ← w[0] + t
･ x[1] - y[1] + t
･ v[1] - w[1] + t
･ i ← 2
</pre>
</td>
</tr>
</tbody>
</table>
<dl class="inline">
<dt>設問 1</dt>
<dd>次の記述中の<span class="blank"></span>に入れる正しい答えを，解答群の中から選べ。</dd>
<dl>
<div class="mag_lt10 mag_h30">表 2 において，最適化の方法を (1)，(2)，(3) の順で適用するとき， (2) で適用される最適化の方法は<span class="blank">a</span>であり， (2) で適用される最適化の方法は<span class="blank">b</span>である。</div>
<p>a， b に関する解答群<br />
ア　関数のインライン展開　　<br class="hide-on-med-and-up">イ　共通部分式の削除<br />
ウ　定数の畳込み　　<br class="hide-on-med-and-up">エ　定数伝播<br />
オ　無用命令の削除　　<br class="hide-on-med-and-up">カ　ループ内不変式の移動<br />
キ　ループのアンローリング
</div>
<p>前半部の設問 1 を解いてみましょう。</p>
<p>表 1 に最適化の方法の具体例が示されていて、表 2 の (2) と (3) で適用されている方法が、どの方法に該当するかを答える問題です。せっかくなので、表 2 の (1) から説明しましょう。最適化は、(1) → (2) → (3) の順に進んで行くからです。</p>
<p>以下に、最適化する前のプログラムと、 (1) で最適化した後のプログラムを示します。</p>
<figure class="mag_h30"><figcaption>最適化する前のプログラム</figcaption><pre>
■ i : 0, i ≦ 1, 1
| • x[i] ← y[i] + m + n
| • v[i] ← w[1] + m + n
■
</pre>
</figure>
<figure class="mag_h30"><figcaption>(1) で最適化した後のプログラム</figcaption><pre>
■ i : 0, i ≦ 1, 1
| ･ t ← m + n
| ･ x[i] ← y[i] + t
| ･ v[i] ← w[i] + t
■
</pre>
</figure>
<p>繰り返し処理の中で、同じ<code>m + n</code>という加算が 2 回行われています。これは、無駄なことです。</p>
<p>そこで、<code>・t ← m + n</code>という処理を追加して加算結果を変数 t に代入し、これまでの<code>m + n</code>の部分を<code>t</code>に置き換えています。これによって、加算は 1 回だけになります。</p>
<p>これは、表 1 の中で</p>
<blockquote class="grey-text"><p>同じ式が複数の個所に存在し、それらの式で使用している変数の値が変更されず、式の値が変化しないとき、その式の値を作業用変数に格納する文を追加し、複数の同じ式をその作業用変数で置き換える</p></blockquote>
<p>に該当するので、「共通部分式の削除」です。ここでは、 t が作業用変数です。</p>
<p>&nbsp;</p>
<p>以下に、 (1) で最適化した後のプログラムと、 (2) で最適化した後のプログラムを示します。</p>
<figure class="mag_h30"><figcaption>(1) で最適化した後のプログラム</figcaption><pre>
■ i : 0, i ≦ 1, 1
| ･ t ← m + n
| ･ x[i] ← y[i] + t
| ･ v[i] ← w[i] + t
■
</pre>
</figure>
<figure class="mag_h30"><figcaption>(2) で最適化した後のプログラム</figcaption><pre>
･ t ← m + n
■ i : 0, i ≦ 1, 1
| ･ x[1] ← y[1] + t
| ･ v[1] ← w[1] + t
■
</pre>
</figure>
<p><code>・t ← m + n</code>において、 m + n の演算結果と、変数 t に代入される値は、繰り返し処理の中で、常に同じです。同じ演算と代入を繰り返すのは、無駄なことです。</p>
<p>そこで、<code>・t ← m + n</code>を繰り返しの外に出しています。</p>
<p>これは、表 1 の中で</p>
<blockquote class="grey-text"><p>ループ中で値の変化しない式があるとき、その式をループの外に移動する</p></blockquote>
<p>に該当するので、「ループ内不変式の移動」です。したがって、空欄 a の正解は、選択肢カです。ループ（ loop ）とは、「繰り返し」という意味です。</p>
<p>&nbsp;</p>
<p>以下に、 (2) で最適化した後のプログラムと、 (3) で最適化した後のプログラムを示します。</p>
<figure class="mag_h30"><figcaption>(2) で最適化した後のプログラム</figcaption><pre>
･ t ← m + n
■ i : 0, i ≦ 1, 1
| ･ x[1] ← y[1] + t
| ･ v[1] ← w[1] + t
■
</pre>
</figure>
<figure class="mag_h30"><figcaption>(3) で最適化した後のプログラム</figcaption><pre>･ t ← m + n
･ x[0] ← y[0] + t
･ v[0] ← w[0] + t
･ x[1] - y[1] + t
･ v[1] - w[1] + t
･ i ← 2
</pre>
</figure>
<p><code>■ i：0, i ≦ 1, 1</code>という構文を使った繰り返し処理は、 2 回の繰り返しを行います。たった 2 回の繰り返しのために、変数 i を 0 に初期化し、<code>i ≦ 1</code>というチェックと変数 i に 1 を加算する処理を毎回行うのは、無駄なことです。</p>
<p>そこで、<code>■ i：0, i ≦ 1, 1</code>という構文を使った繰り返しをやめて、 2 回の処理を、そのまま記述しています。プログラムが長くなりましたが、変数 i に関する処理がなくなったので、実行速度は速くなります。</p>
<p>これは、表 1 の中で</p>
<blockquote class="grey-text"><p>ループ中の繰り返しの処理を展開する</p></blockquote>
<p>に該当するので、「ループのアンローリング」です。したがって、空欄 b の正解は、選択肢キです。</p>
<h2>コンパイラの最適化に関する午後問題（最適化の弊害）</h2>
<p>設問 2 は省略して、後半部の設問 3 を解いてみましょう。</p>
<div class="card-panel mag_h30">
<dl class="inline">
<dt>設問 3</dt>
<dd>次の記述中の<span class="blank"></span>に入れる適切な答えを，解答群の中から選べ。</dd>
</dl>
<div class="mag_lt10 mag_h10">最適化をしないときと最適化をしたときとで浮動小数点数の演算の結果が異なる場合がある。プログラム 1 に対して表 2 の最適化をしなかったものと，最適化 をしたものとに， y[0] = 3307000000.0， y[1] = 305000000.0， m = -303000000.0， n = 4.0 を与えて実行した。その結果の x[0]， x[1] が次のとおりになった。ここで，同一優先順位の算術演算子は，左から順に演算する。</p>
<dl class="inline mag_lt10 mag_h10">
<dt>最適化をしないとき:</dt>
<dd style="margin-left:10em">x[0] = 4000004.0, x[1] = 2000004.0</dd>
<dt>最適化をしたとき:</dt>
<dd style="margin-left:10em">x[0] = 4000000.0, x[1] = 2000000.0</dd>
</dl>
<p>この実行結果が異なる原因としては，<span class="blank">d</span>の方法の適用によって演算順序が変化したことで，<span class="blank">e</span>が発生したからである。ここで，浮動小数点数の演算は単精度 (仮数部は 23 ビット) で計算しているものとする。
</div>
<p>d に関する解答群</p>
<p>ア　関数のインライン展開　　<br class="hide-on-med-and-up">イ　共通部分式の削除<br />
ウ　定数の畳込み　　<br class="hide-on-med-and-up">エ　定数伝播<br />
オ　無用命令の削除　　<br class="hide-on-med-and-up">カ　ループ内不変式の移動<br />
キ　ループのアンローリング</p>
<p>e に関する解答群</p>
<p>ア　桁あふれ　　イ　桁落ち　　<br class="hide-on-med-and-up">ウ　情報落ち　　エ　丸め誤差
</div>
<p>この設問の内容は、「最適化をしたら、浮動小数点数の演算の結果に誤差が生じてしまった」ということです。</p>
<p>最適化をしないときの　x[0] = 4000004.0 と x[1] = 2000004.0 は、正しい値です。</p>
<p>それに対して、最適化をしたときの x[0] = 4000000.0 と x[1] = 2000000.0 では、 4.0 の部分が失われて、誤差が生じています。</p>
<p>これは、浮動小数点数において、大きな値と小さな値を加算または減算すると、大きな値の指数に合わせて演算されるので、小さな値が 0 になってしまう（情報が消えてしまう）、という誤差であり、<span class="bold">情報落ち</span>と呼ばれます。</p>
<p>したがって、空欄 e の正解は、選択肢ウです。</p>
<p>&nbsp;</p>
<p>ここでは、 y[0] = 307000000.0, y[1] = 305000000.0, m = -303000000.0, n = 4.0 なので、 y[0], y[1], m が大きな値であり、 n が小さな値です。</p>
<p>問題文に</p>
<blockquote class="grey-text"><p>同一優先順位の算術演算子は、左から順に演算する</p></blockquote>
<p>とあるので、最適化をしたことによって、演算の順序が変わってしまい、大きな値と小さな値の加算または減算が生じたのです。</p>
<p>&nbsp;</p>
<p>以下は、最適化する前のプログラム（最適化をしないときのプログラム）です。</p>
<figure class="mag_h30"><figcaption>最適化する前のプログラム</figcaption><pre>
■ i : 0, i ≦ 1, 1
| • x[i] ← y[i] + m + n
| • v[i] ← w[1] + m + n
■
</pre>
</figure>
<p><code>・x[i] ← y[i] + m + n</code>という演算では、まず、 y[i] と m という大きな値どうしの加算が行われ、その結果として小さな値が得られます。</p>
<p>次に、その小さな値と n という小さな値どうしの加算が行われます。これなら、情報落ちは生じません。これは、<code>・v[i] ← w[i] + m + n</code>の部分でも同様です。</p>
<p>&nbsp;</p>
<p>以下は、 (1) で最適化した後のプログラムです。</p>
<figure class="mag_h30"><figcaption>(1) で最適化した後のプログラム</figcaption><pre>
■ i : 0, i ≦ 1, 1
| ･ t ← m + n
| ･ x[i] ← y[i] + t
| ･ v[i] ← w[i] + t
■
</pre>
</figure>
<p>問題の前半部で説明した「共通部分式の削除」という方法で、<code>・t ← m + n</code>という処理を行っています。</p>
<p>これは、 m という大きな値と、 n という小さな値の加算なので、情報落ちが生じる場合があります。</p>
<p>したがって、空欄 d の正解は、選択肢イです。</p>
<div class="grey lighten-5 mag_h30 pad_20 c-round">
<i class="material-icons light-blue-text">search</i><span class="blue-grey-text mag_w10">タグで関連記事をチェック</span><a href="../../tag/情報落ち/" class="tag">情報落ち</a>
</div>
<p>&nbsp;</p>
<p><span class="chip mag_rt05">解答</span>設問 1　a &#8211; カ, b &#8211; キ　設問 3　d &#8211; イ, e &#8211; ウ</p>
<div class="divider mag_h50"></div>
<p>いかがでしたか？</p>
<p>午前問題と午後問題のセットで、コンパイラの最適化を、しっかりと理解できたでしょう。</p>
<p>この連載では、今後も、多くの受験者が苦手としている用語を取り上げて行きます。それでは、またお会いしましょう！</p><p>The post <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/mastering_tech/compiler_optimization/">基本情報でわかる コンパイラ 最適化</a> first appeared on <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi">基本情報技術者試験 受験ナビ｜科目A・科目B対策から過去問解説まで 250本以上の記事を掲載</a>.</p>]]></content:encoded>
			</item>
		<item>
		<title>午後問題の歩き方 &#124; 午後問題の読み方 ～ソフトウェア OS</title>
		<link>https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/gogo_arukikata/guide_sw_of_questions_at_pm/</link>
		<pubDate>Thu, 21 Jun 2018 05:35:28 +0000</pubDate>
		<dc:creator><![CDATA[矢沢 久雄]]></dc:creator>
				<category><![CDATA[FIFO LRU LFU]]></category>
		<category><![CDATA[ソフトウェア]]></category>
		<category><![CDATA[午後問題の解説]]></category>
		<category><![CDATA[消去法のやり方]]></category>

		<guid isPermaLink="false">http://www.seplus.jp/dokushuzemi/fe/fenavi/?post_type=gogo_arukikata&#038;p=233</guid>
		<description><![CDATA[<p>ソフトウェアの午後問題のテーマは、 「 OS 」 「コンパイラ」 「その他」 に大きく分類できます。 これらの中で OS に関する問題がよく出題されるので、過去問題をよく練習しておきましょう。 ここでは、例として、平成  [&#8230;]</p>
<p>The post <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/gogo_arukikata/guide_sw_of_questions_at_pm/">午後問題の歩き方 | 午後問題の読み方 ～ソフトウェア OS</a> first appeared on <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi">基本情報技術者試験 受験ナビ｜科目A・科目B対策から過去問解説まで 250本以上の記事を掲載</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>ソフトウェアの午後問題のテーマは、</p>
<ul class="background">
<li class="bold">「 OS 」</li>
<li class="bold">「コンパイラ」</li>
<li class="bold">「その他」</li>
</ul>
<p>に大きく分類できます。</p>
<p>これらの中で OS に関する問題がよく出題されるので、過去問題をよく練習しておきましょう。</p>
<p>ここでは、例として、<a href="https://www.jitec.ipa.go.jp/1_04hanni_sukiru/mondai_kaitou_2013h25_1/2013h25h_fe_pm_qs.pdf#page=9" rel="noopener" target="_blank">平成 25 年度 春期 午後 問 2「仮想記憶方式」</a>を紹介します。仮想記憶は、OS の機能のひとつです。</p>
<div class="card-panel blue-grey-text z-depth-0 grey lighten-5 mag_h30">
<i class="material-icons blue-text">error</i> <span class="small-text">本記事ではわかりやすいよう、問題に記号を入れています</span>
</div>
<style>dl.inline dd{margin-left:2em}</style>
<h2>長々とした説明と難しそうな図にまどわされるな</h2>
<p>以下は、問題の冒頭部分です。長々とした説明と、いかにも難しそうな図が示されています。</p>
<p>午後問題の問 2 ～問 7 は、選択問題（ 6 問中 4 問選択）です。</p>
<p>はたして、皆さんは、この説明と図を見て、この問題を選択するでしょうか。おそらく、しないでしょう。</p>
<p>しかし、<span class="bold">それは誤った判断</span>です。</p>
<p>実は、この問題は、あとで設問を見ればわかりますが、とっても簡単なのです。この説明と図を見なくても解けます。</p>
<div class="card-panel mag_h30">
問 2　仮想記憶方式に関する次の記述を読んで，設問 1 ～ 3 に答えよ。</p>
<p>　OS の主記憶管理において，仮想記憶方式は， OS が提供する論理的な記憶領域 (以下，仮想記憶という) 上のアドレスと主記憶上の物理的なアドレスを対応付けて管理する方式である。仮想記憶方式では，補助記憶装置を仮想記憶として用いるので，仮想記憶上に主記憶の容量を超えるプログラムを格納することができる。仮想記憶上のアドレス空間を仮想アドレス空間，主記憶上のアドレス空間を物理アドレス空間と呼び，それぞれの空間の記憶場所を仮想アドレスと物理アドレスで指定する。</p>
<p>　仮想記憶方式の一つに，ページング方式がある。ページング方式は，仮想アドレス空間と物理アドレス空間のそれぞれをページと呼ぶ固定長の領域に分割しておき，ページ単位でアドレス空間を管理する。ページング方式による仮想アドレス空間のページと物理アドレス空間のページの対応例を，図 1 に示す。図 1 では，補助記憶装置に格納されているプログラム A は a1 ， a2 ， a3 ， a4 ， a5 に分割されて，仮想ページ番号 1 ～ 5 のページに格納されている。</p>
<p><img class="mag_h30 hoverable materialboxed" src="../../wp-content/uploads/2018/06/Q2_figure1_h25_spring.png" alt="" style="width: 90%; margin: auto;" /></p>
<p>　仮想アドレス空間及び物理アドレス空間の各ページには，先頭から順に番号を付け，それぞれを仮想ページ番号，物理ページ番号と呼ぶ。仮想ページと物理ページの対応は，ページテーブルで管理する。ページテーブルの要素の個数は仮想ページの個数と同じであり，各要素が仮想ページの 1 ページに対応している。ページテーブルでは，仮想ページの内容が物理アドレス空間にも存在しているかどうかを示すビット (以下，存在ビットという) と物理ページ番号が管理されている。存在ビットは，ページが存在しているとき 1 ，存在していないとき 0 とする。
</p></div>
<p>それでは、なぜ、問題の冒頭に、長々とした説明と難しそうな図があるのでしょうか。</p>
<p>仮想記憶には、様々な形式があるので、単に「仮想記憶において、以下の設問に答えよ」という問題では、あとで受験者から<span class="bold">「どういう形式の仮想記憶を想定しているかによって、答えが違ってくるので、この問題は解けないじゃない！」というクレームが来てしまう</span> かもしれないからです。</p>
<p>もしも、筆者が出題者だったら「ごく普通に基本情報技術者試験の勉強をされた皆さんがご存知の仮想記憶において」という前置きにしますが、実際の試験の出題者は、そんなくだけたことを書けませんので、長々とした説明と難しそうな図があるのです（これは、筆者の推測です）。</p>
<h2>先に選択肢を見れば、落ち着いて正解を選べる</h2>
<p>冒頭の長々とした説明と難しそうな図は気にしないで、設問 1 を見てみましょう。</p>
<p>ここにも、問題解法のポイントがあります。それは、<span class="bold">設問の文章よりも、選択肢に注目すること</span>です。</p>
<p>設問の文章は、長々とした説明になっていて難しそうに見える場合がありますが、選択肢を見ると、「な～んだ、自分の知っている言葉ばかりじゃないか！」ということがよくあります。</p>
<p>ですから、まず選択肢を見て、それから設問の文書を読めば、落ち着いて正解を選ぶことができます。</p>
<p>&nbsp;</p>
<p>以下は、実際の試験問題と同じに「設問の文書」→「選択肢の順」に並べたものです。これは、ちょっと難しい感じがするでしょう。</p>
<div class="card-panel mag_h50">
<p>　プログラムの実行過程で存在ビットを調べプログラムの実行に必要なページが <span class="blank">a</span> に存在していないときには，ページフォールトという割込みが発生する。ページフォールトが発生すると，ページアウトやページインなどのページ置換え処理が実行される。ページ置換え処理のアルゴリズムには，ページインしてから最も時間が経過しているページを置換え対象とする FIFO アルゴリズムや，参照されていない時間が最も長いページを置換え対象とする。 <span class="blank">b</span> アルゴリズムなどがある。</p>
<p>設問 1</p>
<p>次の記述中の <span class="blank"></span> に入れる正しい答えを，解答群の中から選べ。</p>
<p>解答群<br />
ア　LFU　　<br class="hide-on-med-and-up">イ　LIFO　　<br class="hide-on-med-and-up">ウ　LRU<br />
エ　仮想アドレス空間　　<br class="hide-on-med-and-up">オ　物理アドレス空間
</div>
<p>以下は、実験的に「選択肢」→「設問の文章」の順に並べたものです。</p>
<p>さっきより、簡単になったように感じませんか。問題を解くときには、、<span class="bold">選択肢 → 設問の文書</span> の順に見ることをオススメします。</p>
<div class="card-panel mag_h50">
設問 1</p>
<p>次の記述中の <span class="blank"></span> に入れる正しい答えを，解答群の中から選べ。</p>
<p>解答群<br />
ア　LFU　　<br class="hide-on-med-and-up">イ　LIFO　　<br class="hide-on-med-and-up">ウ　LRU<br />
エ　仮想アドレス空間　　<br class="hide-on-med-and-up">オ　物理アドレス空間</p>
<p>（設問の文章）<br />
　プログラムの実行過程で存在ビットを調べプログラムの実行に必要なページが <span class="blank">a</span> に存在していないときには，ページフォールトという割込みが発生する。ページフォールトが発生すると，ページアウトやページインなどのページ置換え処理が実行される。ページ置換え処理のアルゴリズムには，ページインしてから最も時間が経過しているページを置換え対象とする FIFO アルゴリズムや，参照されていない時間が最も長いページを置換え対象とする。 <span class="blank">b</span> アルゴリズムなどがある。
</div>
<p>仮想記憶では、プログラムを「ページ」と呼ばれる固定サイズに区切り、実行に必要なページを「物理メモリ（電子的なメモリ）」に置きます。必要なページが実メモリに存在しないことを「ページフォルト（ page fault ）」と呼びます。</p>
<p>したがって、空欄 a に入るのは、選択肢オの「物理アドレス空間」です。</p>
<h2>3 点セットで覚えてほしい FIFO、LRU、LFU</h2>
<p>今度は、設問 1 の空欄 b です。</p>
<p>ページフォルトが生じたときには、物理メモリに置かれたページの中で、今後使われる可能性が最も低いページを、「仮想メモリ（ハードディスク）」に書き込んで（ページアウト）から、必要なページを物理メモリに読み込み（ページイン）します。</p>
<p>今後使われる可能性が最も低いページを判断する方法には、「 FIFO 」「 LRU 」「 LFU 」の3つがあり、これらを「ページ置換えアルゴリズム」と呼びます。</p>
<p>&nbsp;</p>
<p>ページ置換えアルゴリズムは、午前問題でとてもよく出題されています。</p>
<p>筆者は、独自に「よく出る問題と用語 Top 100」を調べたことがあるのですが、ページ置換えアルゴリズムの中の LRU は、Top 10 に入っています。</p>
<p>この問題の答えも、LRU（選択肢ウ）です。</p>
<p>&nbsp;</p>
<p>FIFO 、LRU 、LFU は、3 点セットで覚えてください。略語のままではなく、略語の意味を調べて、日本語に訳して覚えましょう。</p>
<dl class="background c-round">
<dt class="post-title">FIFO ＝ First In First Out</dt>
<dd>最初にページインしたページを最初にページアウトする。</dd>
<dt class="post-title">LRU ＝ Least Recently Used</dt>
<dd>最も最近に使われていないページをページアウトする（最後に使われてから最も時間が経過しているページをページアウトする）</dd>
<dt class="post-title">LFU ＝ Least Frequently Used</dt>
<dd>最も頻繁に使われていないページをページアウトする（使われた回数が最も少ないページをページアウトする）</dd>
</dl>
<p><i class="material-icons indigo-text mag_h30">label</i> 関連タグ: <a href="../../tag/fifo-lru-lfu/" class="tag">FIFO LRU LFU</a></p>
<h2>処理の順番を問う問題は、消去法でやればいい</h2>
<p>設問 2 は、ページフォルトが発生したときに、どのような順序でページの置き換え（ページアウトとページイン）が行われるかという問題です。この問題を見て、どう思いますか？</p>
<p>「そんなの知らないよ！」と思うでしょう。筆者も、同じです。</p>
<p>でも、大丈夫です。知らなくても、常識的な判断で正解できます。</p>
<div class="card-panel mag_h50">
設問 2</p>
<p>プログラム A を実行するために割り当てられた物理アドレス空間の物理ページの個数が 3 の場合を考える。プログラム A の実行過程において，物理アドレス空間に a1， a2， a3 が存在している状態で a4 を参照するとページフォールトが発生する。このページフォールトが発生した後の処理の流れとして適切な答えを，解答群の中から選べ。ここで，解答群中の処理は左から右に向かって行うものとする。</p>
<p>【処理の単位】</p>
<dl class="inline">
<dt>①</dt>
<dd>退避させるページをページアウトする。</dd>
<dt>②</dt>
<dd>ページ置換えアルゴリズムによって，物理アドレス空間からページアウトするページを決定する。 </dd>
<dt>③</dt>
<dd>実行に必要なページをページインする。 </dd>
<dt>④</dt>
<dd>ページアウトしたページに対応するページテーブルの要素の存在ビットを 0 にする。</dd>
<dt>⑤</dt>
<dd>ページインしたページに対応するページテーブルの要素の存在ビットを 1 にする。</dd>
<dt>⑥</dt>
<dd>ページアウトしたページに対応するページテーブルの要素の物理ページ番号を設定する。</dd>
<dt>⑦</dt>
<dd>ページインしたページに対応するページテーブルの要素の物理ページ番号を設定する。</dd>
</dl>
<p>解答群<br />
ア　①→②→③→④→⑤→⑥　　<br class="hide-on-med-and-up">イ　①→③→②→④→⑦→⑤<br />
ウ　②→①→④→③→⑤→⑥　　<br class="hide-on-med-and-up">工　②→①→④→③→⑦→⑤<br />
オ　②→③→①→④→⑤→⑥　　<br class="hide-on-med-and-up">力　②→③→⑤→⑥→①→④
</div>
<p><span class="bold">処理の順番を問う問題は、選択肢の違いに注目して「これば違う」と判断できたものを消して行けばよい</span> のです。つまり消去法です。</p>
<p>&nbsp;</p>
<p>選択肢には、<span class="u">1 番目の手順が ①（ページアウトする）のものと、②（ページアウトするページを決定する）のもの</strong> があります。</p>
<p>常識的に考えて、ページアウトするページを決定しなければ、ページアウトできないはずですから、1 番目の手順が ① の選択肢に <span class="bold"> <i class="material-icons red-text">clear</i> </span> を付けて消去します。</p>
<div class="card-panel mag_h50">
解答群</p>
<p><span class="bold"><i class="material-icons red-text">clear</i></span>ア①→②→③→④→⑤→⑥　　<br class="hide-on-med-and-up"><span class="bold"><i class="material-icons red-text">clear</i></span>イ①→③→②→④→⑦→⑤<br />
ウ　②→①→④→③→⑤→⑥　　<br class="hide-on-med-and-up">工　②→①→④→③→⑦→⑤<br />
オ　②→③→①→④→⑤→⑥　　<br class="hide-on-med-and-up">力　②→③→⑤→⑥→①→④
</div>
<p>残った選択肢には、<span class="u">2 番目の手順が ①（ページアウトする）のものと、③（ページインする）のもの</span> があります。</p>
<p>常識的に考えて、ページアウトしてページを空けないとページインできないはずですから、2 番目の手順が ③ の選択肢に <span class="bold"><i class="material-icons red-text">clear</i></span> を付けて消去します。</p>
<div class="card-panel mag_h50">
解答群</p>
<p><span class="bold"><i class="material-icons red-text">clear</i></span>ア①→②→③→④→⑤→⑥　　<br class="hide-on-med-and-up"><span class="bold"><i class="material-icons red-text">clear</i></span>イ①→③→②→④→⑦→⑤<br />
ウ　②→①→④→③→⑤→⑥　　<br class="hide-on-med-and-up">工　②→①→④→③→⑦→⑤<br />
<span class="bold"><i class="material-icons red-text">clear</i></span>オ　②→③→①→④→⑤→⑥　　<br class="hide-on-med-and-up"><span class="bold"><i class="material-icons red-text">clear</i></span>力　②→③→⑤→⑥→①→④
</div>
<p>残った選択肢は、ウとエです。</p>
<p>両者は、<span class="u">②（ページアウトするページを決定する）→ ①（ページアウトする）→ ④（ページアウトしたページの存在ビットを 0 にする）→ ③（ページインする）まで同じ</span> です。</p>
<p>その後は、</p>
<p>選択肢ウでは、⑤（ページインしたページの存在ビットを1にする）→ ⑥（ページアウトしたページの物理ページ番号を設定する）です。</p>
<p>選択肢エ では、⑦（ページインしたページの物理ページ番号を設定する）→ ⑤（ページインしたページの存在ビットを 1 にする）です。</p>
<p>&nbsp;</p>
<p>ここは、ちょっと悩むかもしれませんが、常識的に考えてください。</p>
<p>ページアウトしたページは、もはや物理メモリには存在していないのです。</p>
<p>したがって、手順の中に ⑥（ページアウトしたページの物理ページ番号を設定する）がある選択肢ウは、不適切であるとわかります。</p>
<p>残った選択肢エが正解です。</p>
<p><i class="material-icons indigo-text mag_h50">label</i> 関連タグ: <a href="../../tag/消去法のやり方" class="tag">消去法のやり方</a></p>
<h2>コツコツと解く問題も練習しておこう</h2>
<p>最後の設問 3 は、「 FIFO（ First In First Out ）のページ置換えアルゴリズムで、物理ページが 3 の場合と 4 の場合において、それぞれページフォルトが何回発生するか実際にやってみよ」という問題です。</p>
<p>この手の問題は、絵を描いてコツコツと解くしかありません。ひたすら練習あるのみです。</p>
<p>実際の試験の前に、この手の問題に遭遇できたことをラッキーだと思って、丁寧に練習してください。</p>
<div class="card-panel">
設問 3</p>
<p>次の記述中の <span class="blank"></span> に入れる正しい答えを，解答群の中から選べ。</p>
<p>ページ置換えアルゴリズムとして FIFO アルゴリズムを採用する。プログラムの実行過程で仮想ページが次の順で参照されるとき，物理ページの個数が3の場合のページフォールトの回数は <span class="blank">c</span> 回である。そして，物理ページの個数を 4 に増やした場合のページフォールトの回数は <span class="blank">d</span> 回である。ここで，プログラムの実行開始時点では，物理アドレス空間にはどのページも存在していないものとする。</p>
<p>【仮想ページの参照順を示す仮想ページ番号の並び】<br />
1 → 4 → 3 → 2 → 1 → 4 → 5 → 1 → 4 → 3 → 2 → 5 → 1</p>
<p>解答群</p>
<p>ア　8　　イ　9　　ゥ　10　　ェ　11　　オ　12
</p></div>
<p>物理ページが 3 の場合は、以下のようになります。ここでは、［　］でページを示しています。</p>
<p>ページフォルト（参照するページがないので、ページインする）は、全部で 10 回なので、空欄 c はウです。</p>
<table class="bordered mag_h40">
<thead>
<tr>
<th>［ ］</th>
<th>［ ］</th>
<th>［ ］</th>
<th>初期状態</th>
</tr>
</thead>
<tbody>
<tr>
<td>［1］</td>
<td>［ ］</td>
<td>［ ］</td>
<td>1 を参照（ページフォルト）</td>
</tr>
<tr>
<td>［1］</td>
<td>［4］</td>
<td>［ ］</td>
<td>4 を参照（ページフォルト）</td>
</tr>
<tr>
<td>［1］</td>
<td>［4］</td>
<td>［3］</td>
<td>3 を参照（ページフォルト）</td>
</tr>
<tr>
<td>［2］</td>
<td>［4］</td>
<td>［3］</td>
<td>2 を参照（ページフォルト）</td>
</tr>
<tr>
<td>［2］</td>
<td>［1］</td>
<td>［3］</td>
<td>1 を参照（ページフォルト）</td>
</tr>
<tr>
<td>［2］</td>
<td>［1］</td>
<td>［4］</td>
<td>4 を参照（ページフォルト）</td>
</tr>
<tr>
<td>［5］</td>
<td>［1］</td>
<td>［4］</td>
<td>5 を参照（ページフォルト）</td>
</tr>
<tr>
<td>［5］</td>
<td>［1］</td>
<td>［4］</td>
<td>1 を参照</td>
</tr>
<tr>
<td>［5］</td>
<td>［1］</td>
<td>［4］</td>
<td>4 を参照</td>
</tr>
<tr>
<td>［5］</td>
<td>［3］</td>
<td>［4］</td>
<td>3 を参照（ページフォルト）</td>
</tr>
<tr>
<td>［5］</td>
<td>［3］</td>
<td>［2］</td>
<td>2 を参照（ページフォルト）</td>
</tr>
<tr>
<td>［5］</td>
<td>［3］</td>
<td>［2］</td>
<td>5 を参照</td>
</tr>
<tr>
<td>［1］</td>
<td>［3］</td>
<td>［2］</td>
<td>1 を参照（ページフォルト）</td>
</tr>
</tbody>
</table>
<p>物理ページが 4 の場合は、以下のようになります。ページフォルトは、全部で 11 回なので、空欄 d はエです。</p>
<table class="bordered mag_h40">
<thead>
<tr>
<th>［ ］</th>
<th>［ ］</th>
<th>［ ］</th>
<th>［ ］</th>
<th>初期状態</th>
</tr>
</thead>
<tbody>
<tr>
<td>［1］</td>
<td>［ ］</td>
<td>［ ］</td>
<td>［ ］</td>
<td>1 を参照（ページフォルト）</td>
</tr>
<tr>
<td>［1］</td>
<td>［4］</td>
<td>［ ］</td>
<td>［ ］</td>
<td>4 を参照（ページフォルト）</td>
</tr>
<tr>
<td>［1］</td>
<td>［4］</td>
<td>［3］</td>
<td>［ ］</td>
<td>3 を参照（ページフォルト）</td>
</tr>
<tr>
<td>［1］</td>
<td>［4］</td>
<td>［3］</td>
<td>［2］</td>
<td>2 を参照（ページフォルト）</td>
</tr>
<tr>
<td>［1］</td>
<td>［4］</td>
<td>［3］</td>
<td>［2］</td>
<td>1 を参照</td>
</tr>
<tr>
<td>［1］</td>
<td>［4］</td>
<td>［3］</td>
<td>［2］</td>
<td>4 を参照</td>
</tr>
<tr>
<td>［5］</td>
<td>［4］</td>
<td>［3］</td>
<td>［2］</td>
<td>5 を参照（ページフォルト）</td>
</tr>
<tr>
<td>［5］</td>
<td>［1］</td>
<td>［3］</td>
<td>［2］</td>
<td>1 を参照（ページフォルト）</td>
</tr>
<tr>
<td>［5］</td>
<td>［1］</td>
<td>［4］</td>
<td>［2］</td>
<td>4 を参照（ページフォルト）</td>
</tr>
<tr>
<td>［5］</td>
<td>［1］</td>
<td>［4］</td>
<td>［3］</td>
<td>3 を参照（ページフォルト）</td>
</tr>
<tr>
<td>［2］</td>
<td>［1］</td>
<td>［4］</td>
<td>［3］</td>
<td>2 を参照（ページフォルト）</td>
</tr>
<tr>
<td>［2］</td>
<td>［5］</td>
<td>［4］</td>
<td>［3］</td>
<td>5 を参照（ページフォルト）</td>
</tr>
<tr>
<td>［2］</td>
<td>［5］</td>
<td>［1］</td>
<td>［3］</td>
<td>1 を参照（ページフォルト）</td>
</tr>
</tbody>
</table>
<div class="divider mag_tp30 mag_bt50"></div>
<p>午後問題の多くは、常識的な判断で解けます。そして、常識的な知識は、午前問題の学習によって得られます。</p>
<p><span class="u">もしも、午後問題で苦手な分野があるなら、その分野の午前問題を数多く解いてください。</span>きっと、苦手を克服できるはずです。</p>
<p>それではまた、お会いしましょう！</p>
<p>&nbsp;</p><p>The post <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/gogo_arukikata/guide_sw_of_questions_at_pm/">午後問題の歩き方 | 午後問題の読み方 ～ソフトウェア OS</a> first appeared on <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi">基本情報技術者試験 受験ナビ｜科目A・科目B対策から過去問解説まで 250本以上の記事を掲載</a>.</p>]]></content:encoded>
			</item>
	</channel>
</rss>
