ARM NEONの使い方 乗算編
今回は乗算編です
特に変わった内容はありません
乗算
サンプル
符号付き16bit整数ベクタの乗算をしてみます
#include <stdio.h> #include <stdint.h> #include <arm_neon.h> int main() { int16_t a[4] = { 1, 2, 3, 4 }; int16_t b[4] = { 5, 6, 7, 8 }; int16x4_t va = vld1_s16(a); int16x4_t vb = vld1_s16(b); int16x4_t vc = vmul_s16(va, vb); int16_t c[4]; vst1_s16(c, vc); for (int i = 0; i < 4; i++) printf("c[%d]: %d\n", i, c[i]); return 0; }
積和演算
みんな大好き(?)積和演算
内積とか計算するときに重宝しますね
サンプル
符号付き16bit整数のベクタの積和演算です
#include <stdio.h> #include <stdint.h> #include <arm_neon.h> int main() { int16_t a[4] = { 1, 1, 1, 1 }; int16_t b[4] = { 2, 2, 2, 2 }; int16_t c[4] = { 3, 3, 3, 3 }; int16x4_t va = vld1_s16(a); int16x4_t vb = vld1_s16(b); int16x4_t vc = vld1_s16(c); int16x4_t vd = vmla_s16(va, vb, vc); int16_t d[4]; vst1_s16(d, vd); for (int i = 0; i < 4; i++) printf("d[%d]: %d\n", i, d[i]); return 0; }
実行結果
d[0]: 7 d[1]: 7 d[2]: 7 d[3]: 7
doubling multiplyってなんぞや
乗算に関しては先ほどのmulとmlaを使うことがほとんどだと思いますが
命令一覧を見ると doubling multiply というのがあったので使ってみました
サンプル
vqdmull(Vector saturating doubling long multiply)を使って乗算をしてみると…
#include <stdio.h> #include <stdint.h> #include <arm_neon.h> int main() { int16_t a[4] = { 1, 2, 3, 4 }; int16_t b[4] = { 5, 6, 7, 8 }; int16x4_t va = vld1_s16(a); int16x4_t vb = vld1_s16(b); int32x4_t vc = vqdmull_s16(va, vb); int32_t c[4]; vst1q_s32(c, vc); for (int i = 0; i < 4; i++) printf("c[%d]: %d\n", i, c[i]); return 0; }
実行結果
c[0]: 10 c[1]: 24 c[2]: 42 c[3]: 64
結果が2倍になった
どうやら乗算してさらに2倍する演算のようです
使い道はあるのかな…
次回
次回は除算編です
ARM NEONの使い方 除算編