さて、テストフレームワークを作るときに問題が一つある。それは、同じ値のセットを二重でチェックする可能性があるということだ。二重でチェックしたら全くの無駄であるため、これを防ぐための機構が必要である。何らかのバグにより同じ値ばかりチェックする可能性もある。
では以下のソースコードを見てみよう。
extern __inline __m128d __attribute__((__gnu_inline__, __always_inline__,__artificial__))
_mm_add_pd (__m128d __A, __m128d __B)
{
return (__m128d) ((__v2df)__A + (__v2df)__B);
}
__m126d
は128ビットの型である。これが2つあるため、このIntrinsic関数においては、チェックされる値は全て合わせて256ビットで表現できることとなる。
2**256
の組み合わせは膨大にあり、Intrinsicnによっては512ビットの型もあるため、その場合は組み合わせは2**1024
となり、すべてを網羅したテーブルを作って管理することは現実的ではない。
ではどうすればいいか、2分木を使えばいい。例えば、1101の値を「チェック済み」にする場合はルートから、1 1 0 1の枝をはやし、最後の葉に帰ってきた値などを格納することとなる。
チェックされていない値は、枝が途中で切れているか、葉がないため、チェックされていないことを確認できることとなる。その場合は、枝と葉を生やし、「チェック済み」とする。
つまり、1024のビットをチェックする場合は、1024の階層の二分木の構造を構築することとなる。
この方法の利点としては、IntelとOpenPOWERをApache Kafkaなどで相互接続する必要がないことである。ファイル移動のみですべてを処理することができる。相互接続して同期機構を作ってもいいがそれはオプションとなる。
あるいはハッシュを使う手がある。入力値にハッシュをかけ、テーブル上のハッシュで指定された場所に「チェック済み」と格納する。そしてテストを実行する。次回からは、入力値にハッシュをかけて、テーブル上のハッシュ値で指定された場所に前の「チェック済み」値がなければ、テストを実行し、「チェック済み」としてそこに格納する。そこにもうすでに値が格納されていれば、もとの入力値を比較し、同じであれば、テストを実行する必要なし、入力値が違ったら、テストを実行し、リスト構造のような鎖をそこから生やして、次回からはリスト構造の根本からチェックしていく。
あるいは、C#やRustなどを使えるとしたら、二重チェックを防ぐためにSetなどが使える。Set(集合)は重複なしに要素を管理できる。
例えば、専用ソフトウェアで二分木構造のテストケースを作る。で、IntelとOpenPOWER上の専用ソフトウェアにそのテストケースのファイルを食わせて、テストを実行し、IntelとOpenPOWERのテスト結果を専用ソフトウェアで照合することとなる。
Special thanks
Hayashizaki Masayukiさん