命令セットアーキテクチャを考える (番外編) 積和演算命令について再考
> ・積和演算命令は備えない(4オペランド必要になるので)
としていますが、積和演算命令は科学技術計算や画像処理・信号処理などで多様されるので、やはり実装したほうがいいのかなと考えてみました。
「ぼくのかんがえたさいきょうのめいれいせっと」では、積和演算が必要な場合、特に短精度データ(単精度の間違いではありません)の場合には、SIMDモード命令と水平演算命令を組み合わせることで、比較的高性能(少ない命令数と少ないクロック数)で実現できると考えていました。
例えば、単精度実数による4次元ベクトルA=(a1,a2,a3,a4)とB=(b1,b2,b3,b4)の内積を計算する場合には以下のようにプログラミングできます。
アドレスAから連続する4ワードにa1,a2,a3,a4が格納され、アドレスBから連続する4ワードにb1,b2,b3,b4が格納されており、その内積をアドレスCに格納するとします。
A: dc float"a1","a2","a3","a4" # dcは定数を定義する(define constant)アセンブラ命令
B: dc float"b1","b2","b3","b4" # 同上
C: da float # daは領域確保を定義する(define area)アセンブラ命令
lea R0,=A,R1 # R1にアドレスAを格納する : offset値(=A)は、アセンブラがPC相対アドレスを計算する
lea R0,=B,R2 # R2にアドレスBを格納する : 同上
lea R0,=C,R3 # R3にアドレスCを格納する : 同上
fldm 2 R1,=0,FR2 # FR2,FR3にベクトルAを格納する
fldm 2 R2,=0,FR4 # FR4,FR5にベクトルBを格納する
fadd v sp FR0,FR0,FR6 # FR6,FR7,FR8,FR9に単精度実数0.0×8個を格納する
fmul v sp FR2,FR4,FR6 # FR6,FR7にa1*b1,a2*b2,a3*b3,a4*b4を単精度実数として計算し、格納する
fhadd sp FR6,FR1 # FR1の下位32bitに、FR6,FR7,FR8,FR9に格納されているa1*b1,a2*b2,a3*b3,a4*b4と0.0*0.0×4個の総和を計算して格納する
fstore sp R3,=0,FR1 # FR1の下位32bitの内容をアドレスCに格納する
アドレス計算やload/store、それにSIMDモード命令のパックドデータ数の調整のためのレジスタクリアを除けば、SIMDモード乗算命令と水平加算命令の計2命令で実現できます。積和演算というくらいなのでベクトル演算を除けば乗算と加算命令で実現できるのは当たり前ですが。ただ、ややこしいといえばややこしいので、積和演算命令(SIMDモード付き)ができれば当然そのほうがプログラマ的にも便利でしょう。
積和演算命令を備えない理由として、4オペランド必要になることを挙げていました。
が、上記の内積計算のように、多くの積和計算処理では各要素データの乗算結果の総和をとるような計算が多いので、A×B+C→DでなくてA×B+C→Cでも、多くの場合、Cの元の値を別レジスタに保存しておく必要はなさそうです。ディストネーションオペランドの意味が微妙に違ってきてしまいますが、眼を瞑ることにして、命令コードフォーマットの問題はひとまず解決とします。
ところが、浮動小数点演算命令はすでに16種類あり、命令コードを「綺麗な形式」で浮動小数点積和演算命令を追加することができません。整数演算命令も命令コードのビットパターンに空きがありません。
命令コードが綺麗な形式で定義できないと、前提条件で書いたような「ダンプデータをみてもプログラムが読める」目的からはずれていってしまいますので好ましくありません。
浮動小数点演算命令の場合は、番外編の「本当の汎用レジスタセット」に書いたように、汎用レジスタと浮動小数点レジスタ間の単純データ転送命令(ビットパターンのままの転送命令)を省略することができれば、この問題は解決します。
(修正)命令数を数え直したら、浮動小数点演算命令は全部で15種類でした(その13は修正しました)。ということで、上記のような変更を加えなくても、命令の追加は可能です。また、逆数の近似値命令と平方根の逆数の近似値命令を、即値ビットを使ってモード指定するようにすれば、命令コードをもう一つ空けることもできます。
整数演算命令の命令コードビットパターンは、load/store/分岐命令が7種類、ビット演算命令も7種類なのでここに埋め込むことも可能です。あまり「綺麗な形式」とはいえませんが。できれば、四則演算命令のパターンのところに追加したいのですが、四則演算というくらいなので命令4種類、それぞれに符号付き二進数と符号なし二進数の場合があるので合計8種類になり、空きがありません。
符号付きと符号なしをどこかの空きビットを使ってモード設定できればいいのですが、その空きビットもありません。即値を10bit指定から減らせば可能ですが、分岐命令のoffset範囲が半分に減っちゃうのは結構影響が大きいように思います。
スワップ命令(1)をビット演算命令(7)のグループと一緒にして、水平演算命令(7)のグループに積和演算命令を追加するのが、比較的綺麗そうですね。
ところで、整数の積和演算命令って必要ですかね。
信号処理などのデジタル化データの場合は浮動小数点データではなくて整数の場合も多いと思います。この命令セットではDSPのような用途は想定していませんけど、静止画像処理とか動画像処理とかは、「普通の」PCやワークステーションでも多く利用される用途でしょう。ってことはやはりあったほうがよさそうです。それに、浮動小数点データのみに積和演算命令を追加というのは、綺麗じゃないですよね。
結論はでないまま、今日のところはここまで。
| 固定リンク
この記事へのコメントは終了しました。


コメント