[パタヘネ:読書メモ]第3章 コンピュータにおける算術演算

3.1 はじめに

この章で取り扱う話題の確認

実数や小数のあわら仕方(内部表現)
32bitに収まらない、大きな数の管理方法
四則演算などの計算は、ハードウェア的にどうやって実装されているのか




3.2 加算と減算


2進の加算処理の基本 -> 情報処理試験レベルなので省略


演算処理では、オーバーフローの考慮が必要。
ソフトウェアの都合で、オーバーフローの検出を行いたい場合があるので、どうやって検出すればよいかを考えてみる。


加算において2つの値の符号が異なる場合は、絶対オーバーフローしない(減算では、符号が同じ時はオーバーフローしない)。

符号が同じ場合はオーバーフローのリスクがあるが、1bit分しかあふれない。
(加算だと、たとえINT_MAX + INT_MAXでも、最大で2倍にしかならないから)



ところで、最上位ビットは符号ビットになっている。
なので、オーバーフローするという事は、”符号ビットの破壊”と同じ意味を指している。



そこまで考えると、オーバーフローの検出は以下のロジックで対応できる事が分かる。

2つの正の数を足した結果、符号ビットがマイナスになった
2つの負の数を足した結果、符号ビットがプラス  になった
	-> このような場合はオーバーフロー!!




上記の場合は、符号付き整数値の話で、符号無しの場合は、オーバーフローは一般に無視される(=検出されない)。




上記の内容を纏めると…
add,addi,sub命令ではオーバーフローがおきると例外(割り込みとも言う)が発生するようになっている。逆にaddu,addiu,subuでは例外は発生しない。

例外が発生すると例外プログラムカウンタ(exception program counter)に例外発生元アドレスが保持され、mfc0命令で値が取得可能になってる。
なので、例外処理を行った上で、処理を続行する事も、ハードウェア的には可能。

また、例外処理用に$k0, $k1という特別なレジスタがある。これは、$atのようにコンパイラが通常使用してはならないレジスタで、例外の復帰処理で使用することが出来る。



また、マルチメディア系の命令(intelのMMXなど)では、オーバーフローしたときに、例外発生ではなくMAX値をセットさせる事も出来る。
これは、ボリューム処理や、クリッピング処理等を考えると、こっちの方が使い勝手が良い場合もある為。

3.3 乗算

まずは、用語の確認

a*b = c の場合...
 
a:被乗数(multiplicand)
b:乗数(multiplier)
c;積(product)




2進での計算方法は,簡単なので説明省略
足し算と異なり、結果値が大きくなりがち(32bit * 32bitの掛け算で、最大64bitになりうる)。

MIPSでは64bitの乗算結果を保存するために2つのレジスタを割り当てており、これらをHi, Loと呼ぶ。
結果が32ビットの場合、Loの値を取得するために、mflo(move from lo)命令を使用する。(上位側はmfhi)
アセンブラでは、この辺は擬似命令を使用することで、詳細を隠蔽している。

乗算は、ハードウェア的には、前述した加算処理とシフト処理で実装できる。
説明は、ちょっと長くなったので別記事で説明してます。
→ [パタヘネ][C]シフトと加算だけで、掛け算を行う


符号処理は、まず符号無しの乗算を行った上で、最後に符号判定を行えばよい。


3.4 除算


除算は、加減算、除算より頻度は低いが計算が面倒で、0除算をチェックする必要もある。

用語の確認

a / b = c あまり d
 
a:被除数(dividend)
b:除数(divisor)
c:商(quotient)
d:剰余(remainder)



計算処理
-> ちょっと複雑そうなので後回し


除算の高速処理としてSRT法、引き放し法、引き戻し法、ノンパフォーミング除算というものがある。
lookupテーブルを使用して、商の推測をするらしい(詳細は後で調べる)


除算の処理は、積の回路を流用できる。

3.5 浮動小数点演算

この節、斜め読みだけしてスキップしました…
余り興味が持てないところで、かつこの後の内容理解には影響しなさそうなので
余裕があったら後で読むかも(でも、たぶん読まない)


3.6 並列処理とコンピュータの算術演算:結合則

順番に処理を行うものを、高速化の為に並列処理化しても、普通結果は変わらないはず。
これを結合則という。

だが、浮動小数点の場合は近似値計算なので、並列化する事によって、微小な差異が出る可能性はありうる。

3.7 実例:x86における浮動小数点演算

省略

3.8 誤信と落とし穴

誤信:左シフトが2^nの掛け算を意味するように、右シフトは割り算を意味する。

signedの値を右シフトする場合は、符号ビットの関係で合わなくなる。
論理シフトではなく算術シフトを使っても合わない。




落とし穴:MIPSのaddiu命令は、16ビットの即値フィールドを符号拡張する

add immediate unsignedなので符号ビットは無視するかと思いきや、実は符号拡張を行う。
この命令は、オーバーフローで例外を出したくない場合に使用する
 
なぜ、そんな仕様になっているかというと、subiu命令というものが存在せず、
addiuは即値にマイナスの数も指定できるというところから来ている。




誤信:浮動小数点形式の演算精度を気にするのは理論数学者だけである。

Pentiumのバグの話。


詳細はこちら -> コンピュータアーキテクチャの話 (90) Pentiumの割り算器のバグ


3.9 おわりに


この章のまとめ

1.コンピュータの計算には、桁数が有限なので精度に制限がある

2.浮動小数点は近似値である事に注意する必要がある

3.計算の並列化により、計算誤差が出る可能性がある


3.10 歴史展望と参考文献(◎CDコンテンツ)

省略

3.11 演習問題

省略

4822284786
コンピュータの構成と設計(上)

関連記事

コメントを残す

メールアドレスが公開されることはありません。