1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

NEONの学習備忘録

Last updated at Posted at 2025-10-26

NEONとは

ArmのSIMD(Single Instruction Multiple Data)拡張機能。
Arm社のページ1によると、以下の演算をサポートしている。

  • 16x8ビット、8x16ビット、4x32ビット、2x64ビットの整数演算
  • 8x16ビット、4x32ビット、2x64ビットの浮動小数点演算

この表記は、データ型xレーン数を表している。例えば整数型uint16x8_tはuint16のデータ8個を、128ビットレジスタに収めた型を意味する。
また、複数のレジスタを束ねた型も定義されている。データ型xデータレーン数xレジスタ本数_t(例: uint16x8x3_t

簡単な例

uint16x8_tのデータ2つを加算する関数

add_uint16.c
#include "arm_neon.h"

void add_uint16_neon(unsigned short int *src1, unsigned short int *src2, unsigned short int *dst) {
  uint16x8_t q1 = vld1q_u16(src1);
  uint16x8_t q2 = vld1q_u16(src2);
  uint16x8_t q0;
  q0 = vaddq_u16(q1, q2);
  vst1q_u16(dst, q0);
}

アセンブリを確認すると、このvaddq_u16は、add.8h v31, v31, v30というベクトル命令にコンパイルされていることがわかる。

$ gcc -g -O add_uint16.c -c -o add_uint16.o
$ objdump -d add_uint16.o

add_uint16.o:	file format mach-o arm64

Disassembly of section __TEXT,__text:

0000000000000000 <ltmp0>:
       0: 3dc0001f     	ldr	q31, [x0]
       4: 3dc0003e     	ldr	q30, [x1]
       8: 4e7e87ff     	add.8h	v31, v31, v30
       c: 3d80005f     	str	q31, [x2]
      10: d65f03c0     	ret

この関数を利用して、以下のようなuint16(unsigned short int)のデータsrc1, src2を入れると、8個分のデータを加算してdstに入れることができる。

add_uint16.c
#include "stdio.h"

void main(void) {
  unsigned short int src1[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
  unsigned short int src2[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
  unsigned short int dst[16];
  add_uint16_neon(src1, src2, dst);
  printf("\tsrc1, \tsrc2, \tdst\n");
  for (size_t i=0; i<16; i++) {
    printf("\t%u, \t%u, \t%u\n", src1[i], src2[i], dst[i]);
  }
}

実行結果では前半8個のデータが加算されている。

$ gcc -g -O add_uint16.c -o exe_add_uint16
$ ./exe_add_uint16
	src1, 	src2, 	dst
	0, 	    0,  	0
	1, 	    1,  	2
	2, 	    2,  	4
	3, 	    3,  	6
	4, 	    4,  	8
	5, 	    5,  	10
    6, 	    6,  	12
	7, 	    7,      14
	8, 	    8, 	    0
	9, 	    9,   	0
	10, 	10, 	0
	11, 	11, 	0
	12, 	12, 	0
	13, 	13, 	0
	14, 	14, 	0
	15, 	15, 	0

src1, src2は16要素あるので、演算するデータ数を16個にしてみる。

add_uint16.c
void add_uint16_neon(unsigned short int *src1, unsigned short int *src2, unsigned short int *dst) {
  uint16x8x2_t q0, q1, q2;
  q1 = vld2q_u16(src1);
  q2 = vld2q_u16(src2);
  q0.val[0] = vaddq_u16(q1.val[0], q2.val[0]);
  q0.val[1] = vaddq_u16(q1.val[1], q2.val[1]);
  vst2q_u16(dst, q0);
}
$ ./exe_add_neon_len
	src1, 	src2, 	dst
	0,  	0,  	0
	1,  	1,  	2
	2,  	2,  	4
	3,  	3,  	6
	4,  	4,  	8
	5,  	5,  	10
	6,  	6,  	12
	7,  	7,  	14
	8,  	8,  	16
	9,  	9,  	18
	10, 	10, 	20
	11, 	11, 	22
	12, 	12, 	24
	13, 	13, 	26
	14, 	14, 	28
	15, 	15, 	30

アセンブリを見るとadd.8hを2回実行していた。

100003e48: 4c40841a    	ld2.8h	{ v26, v27 }, [x0]
100003e4c: 4c40843c    	ld2.8h	{ v28, v29 }, [x1]
100003e50: 4e7c875e    	add.8h	v30, v26, v28
100003e54: 4e7d877f    	add.8h	v31, v27, v29
100003e58: 4c00845e    	st2.8h	{ v30, v31 }, [x2]
100003e5c: d65f03c0    	ret
  1. https://www.arm.com/ja/technologies/neon

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?