はじめに
- この記事はひとり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命令を紹介する。
