はじめに
- この記事はひとりNEONアドベントカレンダー2020 14日目の記事です
- 昨日はニュートン法で割り算と平方根を計算する命令を紹介した。
- 今日はbit演算子命令を紹介する
- 基本的には整数型のみ
-
bsl
には浮動小数点数型を、tst
命令には多項式型を引数に取るタイプの命令が存在する
-
- bitwise AND、bitwise OR、bitwise XOR、bitwise NOT、bitwise NOR、bitwise NANDがある。
- あと
tst
命令とbsl
命令も紹介する
- あと
OpenCVでの実装の参考
- Carotene内の実装
- 実際やってるのはしきい値処理
.cpp
for (; j < roiw8; j += 8)
{
uint8x8_t v0 = vld1_u8(src + j);
uint8x8_t r0 = vcgt_u8(v0, vthreshold8);
uint8x8_t r0a = vbic_u8(v0, r0);
vst1_u8(dst + j, r0a);
}
for (; j < size.width; j++)
{
*(dst + j) = *(src + j) > threshold ? 0 : *(src + j);
}
-
bic
命令を使っているが、引数のr0
は0xff
か0
のどちらかの値を持つ-
cgt
命令は比較命令で、各ベクトルの対応する要素同士でv0 < vthreshold
を評価する - つまり、
v0
がしきい値未満だと、0xff
が入り、それ以外だと0
が入る -
bic
命令は、a AND NOT b
なので、結果、しきい値未満の画素は0
になる
-
-
もう1件、
and
命令の確認
.cpp
for (; j < roiw8; j += 8)
{
uint8x8_t v_src = vld1_u8(src + j);
uint8x8_t v_dst = vand_u8(vcge_u8(v_src, v_lower8), vcle_u8(v_src, v_upper8));
vst1_u8(dst + j, v_dst);
}
for (; j < size.width; j++)
{
u8 srcVal = src[j];
dst[j] = lowerThreshold <= srcVal && srcVal <= upperThreshold ? 255 : 0;
}
-
vand
命令の入力2つはやはり0xff
か0
のどちらか。 - それの
and
を取ることで、所定の条件のときだけ255が書き込まれる - 最後の一文はベクトルで余った端っこの処理なので、ベクトル処理でなく通常のコード処理である
- ベクトル命令と見比べてみると各命令の中身がわかる
早見表
命令 | 引数 | 処理内容 |
---|---|---|
and |
a,b |
a AND b |
orr |
a,b |
a OR b |
eor |
a,b |
a XOR b |
bic |
a,b |
a AND NOT b |
orn |
a,b |
a OR NOT b |
mvn |
a |
NOT a |
tst |
a,b |
(a AND b) == 0 |
bsl |
a,b,c |
c XOR ((c XOR b) AND a) |
tst
-
a AND b
が0になるかどうか。- 0になれば結果は
0xff
のように、各要素の全ビットが立つ - それ以外の場合は、0になる
- bitwise命令というより、比較命令に近いような?そっちに入れておけばよかったかも?
- 0になれば結果は
bsl
- bitセレクトという変わった命令
- 引数を3つ取るが、
- 第1引数(
a
)のbitが1ならば第2引数(b
)からデータを持ってくる - 第1引数(
a
)のbitが0ならば第3引数(c
)からデータを持ってくる - bit単位で
b
とc
の結果をbit単位で組み合わせる命令で、どちらを持ってくるかはa
の内容次第
- 第1引数(
おわりに
- bitwise命令を紹介した。
- bit演算子で結構面白い演算もできるので、この演算の組み合わせで色々やってほしい
- 明日も手島の執筆の予定で、
dup
命令を紹介する。