ぼくのかんがえたさいきょうCPU きょうび除算器ははやらないが

 Alpha,IA-64といった最初から64bitのアーキテクチャで設計されたものには整数除算器が入っていない。また、PowerPC(POWER6)も除算命令はあるものの実行は浮動小数点演算器に任せて結果だけ貰っている。
 除算器が嫌われる理由を挙げてみよう。
(1)演算完了サイクルが不定 被除数と除数の内容によって計算が完了するサイクル数が決まる。これは1命令1サイクル完了を基本とするRISCの思想と相いれない。乗算もそうだがこれは固定サイクルで3~4サイクル程度だからまあ許せるのかも。
(2)0除算割り込みが発生する。
(3) (1)(2)の特徴により、SIMD演算に向かない。
(4)使用頻度が低い割には演算器の規模が大きい。

 浮動小数点演算で除算命令がない場合、どのようにして除算を行っているかというと、除数の逆数を取って被除数との乗算で求めている。逆数は近似値であり、Newton-Raphson法によって正確な逆数を求める。
ニュートン法(Wikipedia)
Newton-Raphson 法(円周率.jp)

 ここでは、従来の方法による除算器について、0除算割り込みが発生しない構成を考える。
まず、SUB命令で除数を0チェックする。→ 0例外判定へ
除数が仮に0であっても、演算結果は符号により飽和、Overflow(V)フラグを立てる。
符号付き32bitの場合(DIVS) -1 ÷ 0 = 0x80000000 with V flag / 1 ÷ 0 = 0x7fffffff with V flag → 0例外判定へ
正しい演算の時はVフラグは立たない。0x7fffffff ÷ 1 の時などは商は0x7fffffff V flag=0。
符号なし除算(DIVU)でも同じ考え。1 ÷ 0 = 0xffffffff with V flag → 0例外判定へ

BCD演算でも同様に、まず最初にBCDSUB GRsx,GR0,GR0でゼロ判定を行う。→ 0例外判定へ
BCDDIV GRsn,0,GRdの結果は9999999999999999999999999999999+または-(31桁の場合) V flagが立つ。→ 0例外判定へ

これで、特に0除算に関する割り込み動作を実装する必要はなくなる。あとの扱いはアプリケーション/OS次第である。
除算命令の前後に判定コードが付くが、除算のサイクル数からいったら微々たるものなので問題ない。
(2)のSIMDに関しては、並列に実行していちばん遅い演算結果が出るまで待ち合わせることになる。途中で例外が発生しないことが保証される。

なおAlphaにはオーバーフロー時に割り込みを上げる機能がある。これをマネすれば0除算割り込みも必要なら実現できる。

ブログ気持玉

クリックして気持ちを伝えよう!

ログインしてクリックすれば、自分のブログへのリンクが付きます。

→ログインへ

なるほど(納得、参考になった、ヘー)
驚いた
面白い
ナイス
ガッツ(がんばれ!)
かわいい

気持玉数 : 0

この記事へのコメント

m.ukai
2009年11月06日 14:56
除算の実装が嫌われるのは、検証が他の演算に比べて面倒臭いというのもあると思います。
それ以外の演算は(乗算でも)本質的には組み合わせ論理ですが除算はステートマシンを組むため検証コストが余計にかかることと、
演算のコーナーケースがやたらとわかりにくいことと。

この記事へのトラックバック