74181でSIMDをする

\[ \newcommand{dn}[3]{\frac{\mathrm{d}^{#3} #1}{\mathrm{d} #2^{#3}}} \newcommand{\d}[2]{\frac{\mathrm{d} #1}{\mathrm{d} #2}} \newcommand{\dd}[2]{\frac{\mathrm{d}^2 #1}{\mathrm{d} {#2}^2}} \newcommand{\ddd}[2]{\frac{\mathrm{d}^3 #1}{\mathrm{d} {#2}^3}} \newcommand{\pdn}[3]{\frac{\partial^{#3} #1}{\partial {#2}^{#3}}} \newcommand{\pd}[2]{\frac{\partial #1}{\partial #2}} \newcommand{\pdd}[2]{\frac{\partial^2 #1}{\partial {#2}^2}} \newcommand{\pddd}[2]{\frac{\partial^3 #1}{\partial {#2}^3}} \newcommand{\p}{\partial} \newcommand{\D}[2]{\frac{\mathrm{D} #1}{\mathrm{D} #2}} \newcommand{\Re}{\mathrm{Re}} \newcommand{\Im}{\mathrm{Im}} \newcommand{\bra}[1]{\left\langle #1 \right|} \newcommand{\ket}[1]{\left|#1 \right\rangle} \newcommand{\braket}[2]{\left\langle #1 \middle|#2 \right\rangle} \newcommand{\inner}[2]{\left\langle #1 ,#2 \right\rangle} \newcommand{\l}{\left} \newcommand{\m}{\middle} \newcommand{\r}{\right} \newcommand{\f}[2]{\frac{#1}{#2}} \newcommand{\eps}{\varepsilon} \newcommand{\ra}{\rightarrow} \newcommand{\F}{\mathcal{F}} \newcommand{\L}{\mathcal{L}} \newcommand{\t}{\quad} \newcommand{\intinf}{\int_{-\infty}^{+\infty}} \newcommand{\R}{\mathcal{R}} \newcommand{\C}{\mathcal{C}} \newcommand{\Z}{\mathcal{Z}} \newcommand{\bm}[1]{\boldsymbol{#1}} \]

SIMD命令とは

x86のAVX命令とか、ArmのNEONのことです。

#include <iostream>
#include <immintrin.h>
int main(){
}

要するに、大きい幅のレジスタを、小さい幅のレジスタの集合とみなして、演算を行う命令です。こうすることで、遊んでいたMSB側の演算器を効率的に使うことができるようになります。

ロジックICでの実装

↑の図を見てわかる通り、演算器間のキャリーを接続したら単一の演算器、キャリーを外したら複数の演算器ということになりますね。

ということで作ってみました。基本的に、74181・74182のアプリケーションノートに書いてある通りの回路です。

キャリーを接続するかしないかを、74マルチプレクサで切り替えます。

8bit単位でやってみる

74182をハックする必要があります。

まとめ

いかがでしたか?

自作CPUに取り入れてみてはいかがでしょうか?

そもそもAVXとかのSIMD命令はレジスタ長が長いほど効果を発揮します。