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 演習問題
省略
コンピュータの構成と設計(上)
関連記事
コメントを残す