SCENE RESEARCH STATION  
with my everyday
thinking-and-doctrine

はじめに

ハードウェアアルゴリズムに関するメモです.

冗長2進表現

桁集合が{-1,0,1}となる2進表現. 通常の2進表現の桁集合は{0,1}である.

冗長2進表現のon-the-fly変換

冗長2進表現から通常の2進表現への逐次変換の事.

例えば冗長2進表現{1,0,-1,0}を2進表現に変換すると{0,1,1,0}となる(いずれも10進数で6を表す).

これを素直な加算と減算で実現すると,-1が入力されたときにキャリーが伝播するため, n桁の変換コストはO(n)となる(桁上げ先見等を使ってもO(log_2 n)である).

キャリーの伝播をなくし定数時間で処理するためには,-1が入力された場合の答え(言い換えるなら1小さい表現)を内部に持てばよい.
通常の表現をP,1小さい表現をNとすれば,変換規則は次のようになる.

入力 1 0 -1
P(i+1) P(i),1 P(i),0 N(i),1
N(i+1) P(i),0 N(i),1 N(i),0

これだけでは分かりにくいので,具体的に冗長2進表現{1,0,-1,0}の変換例を示す.

入力 1 0 -1 0
P(i) {1} {1,0} {0,1,1} {0,1,1,0}
N(i) {0} {0,1} {0,1,0} {0,1,0,1}

以上,桁集合が{-1,0,1}の場合について説明した.より高基数の場合も同様である.Pと基数分小さいNを持てばon-the-fly変換ができる.
冗長4進表現(桁集合{-3,-2,-1,0,1,2,3})の場合の変換規則を以下に示す.

入力 3 2 1 0 -1 -2 -3
P(i+1) P(i),11 P(i),10 P(i),01 P(i),00 N(i),11 N(i),10 N(i),01
N(i+1) P(i),10 P(i),01 P(i),00 N(i),11 N(i),10 N(i),01 N(i),00
表は常にP(i)-1=N(i)となる事を意識すれば簡単に導ける.

冗長4進表現{2,-2,-3,1,-1}を2進表現に変換すると{0,1, 0,1, 0,1, 0,0, 1,1}となる(いずれも10進数では2*4^4-2*4^3-3*4^2+1*2^2-1=339を表す).上記の変換規則でこのon-the-fly変換ができることを確認しよう.

減算シフト型除算法

小学校で習う筆算と全く同じアルゴリズムである.
最上位ビットの桁ぞろえを行い,除数の方が大きければ1を立て,そうでなければ0を立てていく.1を立てた場合は被除数からシフト済みの除数を引く.

除数と被除数の比較と除数を引く減算が必要.比較中に減算を並列に処理すれば,減算のレイテンシは隠蔽できる(比較終了時に減算済みかそうでないものを使うかを選択する).

常に被除数(正確には計算途中の剰余)が負にならないように振舞うため,「回復型」減算シフトとも呼ぶ.

非回復型減算シフト型除算法

減算シフトでは除数を商{0,1}を立てる基準としたが,これは0を基準として商{-1,1}を立てる.0との比較なので1ビットを比較するだけでよい.
商が冗長2進表現になるので,変換処理が必要になる(一般的にはon-the-flyで変換を行うためそのレイテンシは隠蔽できる).
(書きかけ)

指数関数

Y = exp( X )
を求めることを考える.関数を計算によって求める最も基本的な方法は多項式近似である.
しかし,-Inf < X < +Inf の入力範囲を持つ関数の多項式近似は指数関数の場合収束するまで時間がかかりすぎる.
そこで最初の段階で入力範囲を小さくして(レンジリダクション),多項式近似を適用する.

レンジリダクション

Y = exp( X ) = 2^( (1/ln2) X )
なので,
Y = 2 ^ X
と問題を置き換える.Xの整数部をXH,小数部をXLとすれば,
Y = 2 ^ XH * 2 ^ XL
となる.ここで2 ^ XHは単なるシフト(浮動小数点なら指数部に対する加算)になる.よって,2^XL ( 0<=XL<1 )の計算を近似多項式で解く事を考えればよい.

では,0<=x<1の範囲でexp(x)を求めるとき,相対誤差を2^-52以下(倍精度浮動小数点では仮数部が52ビットなので便宜上2^-52にした)にするには何次の近似式が必要かを考える.

多項式近似係数の算出

ここでは分かりやすくテイラー展開を利用して近似多項式の係数を求める.0から1の範囲なので0.5を中心とするテイラー展開を行い,x=0とx=1における誤差を測定する.
(なお0.5は適当に決めたもので,微調整の余地がある.また,端のx=0と1における誤差を測定するのはexp関数の特性による)
係数の算出や誤差の計測はmathematicaを用いると楽である.次のようなコードでm次多項式を利用したときの有効ビット数が分かる

      Clear[F, FT, x, X];
      m = 13;
      F[x_] := 2^x;
      FT[x_] := Normal[Series[F[x], {x, 1/2, m}]];
      FE[X_] := Abs[((FT[x] /. {x -> X})/F[X] - 1];
      Log[2, N[Max[FE[0], FE[1]], 100]]
	
この場合13次の多項式で相対誤差が2^-52以下になる.つまり,指数関数を計算するために13回の積和演算が要る.
(実際はテイラー展開よりも高精度なMiniMax近似を用いた方が良い.mathematicaにMiniMaxApproximationという関数があるのでそれを利用すると楽)

テーブルを利用したレンジリダクション

これでは遅すぎるので,テーブルを利用してさらにレンジリダクションを行う.
y = exp( x1+x2 ) = exp( x1 ) * exp( x2 )
を利用する.
x1をXLの上位nビット,x2を下位ビットとする.ここで,exp(x1)をテーブルから引けば,exp(x2)は 0<=x2<2^-n の範囲における多項式近似で済む.
例えばn=4とした場合,0<=x2<1/16であり,7次の多項式で近似可能である.
nを大きくするかテーブルを複数用意する等すれば,さらに次数を下げることができる.

と,ここまでは単なるアルゴリズムで,ハードウェアアルゴリズムとしてはパイプライン化された積和演算器をどう効率よく使うかが鍵になる.

oldlog 99-00 00-01 01 01-02 02
newlog 2002 2003 2004 2005 2006 2007
category scene | 2ch | 麻雀

Copyright (C) 2003-2004 mitsuman(mnishibe at ertl.jp) All Rights Reserved.

750k+