はじめてのSSE その5

今日はSSE4の命令を紹介します。

// 交差部分(andしたのちに1のbit)があるなら1
#  define Bitboard_Contract(b1,b2) ( ! _mm_testz_si128( (b1).m, (b2).m ) )

// 非0なら1
#  define Bitboard_Test(b)         ( ! _mm_testz_si128( (b).m, _mm_set1_epi8(0xff) ) )


まあご覧の通りです。速度についてもいまさら言うまでもありません。「前者は使えったら使え!」です。後者は、_mm_set1_epi8を使って2命令になっているので、うんぬんかんぬんです。


popcount(1になっているビット数を数える)は、SSE4.2までの命令としては用意されていません。今後用意されるのかどうかはわかりませんが。なかなか不便です。そういや、popcountのpopがpopulationの略だと知ったのは私はつい最近です。みなさん知ってました?


またbsf(bitscanforward)などもSSEの命令としては用意されていません。


bitshiftはSSE2の命令として用意されています。
・_mm_slli_si128(128bit論理左シフト、即値)
・_mm_srli_si128(128bit論理右シフト、即値)
・_mm_srli_epi64(64bit論理右シフト、即値)
など。


言うまでもなくsrliはshift right logical immediateの略です。


ということは、この i がつかない次のようなバージョン
・_mm_srl_epi64(64bit論理右シフト、レジスタ指定)
もあるのですが、
・_mm_srl_epi128(128bit論理右シフト、レジスタ指定)
は存在しません。128bitだとシフト回数が固定でないとしんどかったのでしょうか…。


普通、コンピューター将棋でBitboardのシフトをするのは、歩のBitboardから、歩の利きを求めるために9回シフトする程度でしょうから、あまり問題とはならないかも知れませんが、シフト回数が定数でないとBitboardのシフトはSSE命令を使ってできないというのは知っておいたほうが良いでしょう。


そう言えばBonanza6.0でもシフトはSSEの命令を使っていないようでしたが、使ったほうが速いと思います。ただ、歩の利きを求めるところぐらいにしか出てこないので、効果に乏しいですが…。


つづく