ハードウェア
ある関数fがあって、その関数の中ではAという作業とBという作業をするとする。イメージとしてはこんな感じ。
int f(int arg1){ return B(A(arg1)); }
さて、ここでAという関数とBという関数は、どちらも整数を受け取って整数を返す関数だとしよう。さらに、関数Aおよび関数Bは、奇数を受け取った場合は奇数を返し、偶数を受け取った場合は偶数を返す。そして、内部の中身は、偶数と奇数で違うソースだとしよう。そして、Aでは偶数の方が時間がかかり、Bでは奇数の方が時間がかかるとする。すなわち、
int a(int arg){ if(arg % 2 == 0){ //何かの作業(長い) return (偶数) }else{ //何かの作業(短い) return (奇数) } } int b(int arg){ if(arg % 2 == 0){ //何かの作業(短い) return (偶数) }else{ //何かの作業(長い) return (奇数) } }
というようになっていたとする。
このような場合、最初からfの中で分岐させてやればいいじゃないか、という話もあるが、ソフトウェアの場合は、aとbに意味がある場合には、このように記述した方が良い場合も多い。単なるサブルーチンであれば、もちろん最初から分岐させてaという関数とbという関数を分離しない方が、分岐の数も少なくて早くなる可能性もあるのだけれど、ソフトウェアの場合にはこの程度の分岐であれば無視して、意味を重視した方が良い。もちろん、最初からaとbに意味がない場合には別だけれども。
しかしながら、これの実行時間をシミュレーションする場合には話は変わる。いや、実際には変わらないとも言えるのだけれども、「シミュレータ上では」変わる可能性が高い。というのは、関数fの実行時間の最大値を計算する時に、通常のシミュレータであれば(関数aの実行時間の最大値)+(関数bの実行時間の最大値)を算出するからだ。そして、ハードウェアではまさしくコレが発生する。
・・・と言うことで、faddの高速化にはこんな感じの部分を消すといいよ、とnakajima氏に教えてもらった。