본문 바로가기

Programming/NEON

[NEON] 레인 설정과 조회

NEON 에서는 벡터 안의 레인에 다양한 값을 저장하거나, 레인의 값을 확인할 수 있다. 또한, 하나의 벡터 안에서 레인 사이의 교환(swap)도 가능하다. 레인 설정함수 중 몇 개는 벡터 저장 함수 중에서 브로드캐스트 함수나 레인 저장함수와 결과가 같은데, 이는 어셈블러 명령어 차이에 따른 것으로 성능의 차이는 없다.


1. NEON 레인 설정

NEON 에서는 벡터의 특정 레인의 값을 불러오거나 변경 할수 있다. 

단 레인 설정에 관련된 모든 함수는 복수 벡터에 지원하지 않는다.


1.1 레인 추출 함수

지정된 레인의 값 하나를 일반 변수에 저장한다.

uint16_t r = vgetq_lane_u16(uint16x8_t a, __constrange(0, 7) int lane)

예) lane이 2일때 변수 r에 벡터 a의 2번째 레인 값이 대입된다.


1.2 레인 설정 함수

일반 변수의 값을 지정된 레인에 저장한다.

uint16x8_t r = vsetq_lane_u16(uint16_t value, uint16x8_t vec, __constrange(0, 7) int lane)

예) lane이 2, value = 5일때 벡터 r에서 일반변수 lane 값으로 설정된 레인에 일반 변수 value(5) 값을 대입하고, 

     그외 부분은 벡터 vec의 레인 값을 대입한다.


1.3 비트 패턴을 이용한 레인 초기화 함수

비트 패턴은 비트가 존재하는 형태를 말하며, 예를 들어 uint64_t형 정수 10,421을 2진수로 표현하면 

0x0001000100010001이 된다. 이렇게 2진수로 표현하면 비트가 0과 1로 구성되어 있는데, 이를 비트 패턴이라고 한다.

이러한 비트 패턴을 이용하여 벡터의 레인을 초기화할 수 있다.


uint16x4_t r = vcreate_u16(uint64_t a)

예) uint64_t형 변수의 비트 패턴을 이용하여 벡터를 초기화한다. 변수 a에 10,421을 대입하고 a의 비트 패턴을 이용해서 벡터 r의 레인을 설정한다. 이때 일반 변수 a는 배열이 아니고 일반 변수(uint64_t 형)인 것에 주의해야 한다.


1.4 특정 레인으로 벡터 초기화 함수

벡터 안의 특정 레인 값을 벡터의 모든 레인에 할당한다.

uint16x8_t r = vdupq_lane_u16(uint16x4_t a, __constrange(0, 3) int lane);

예) 벡터 a의 lane번째 값을 벡터 r에 모두 대입한다.


1.5 레인 브로드캐스트 함수

벡터의 모든 레인을 일반 변숫값으로 설정한다. 같은 기능을 하는 함수가 2개 있다.


브로드캐스트 함수

uint16x8_t r = vdupq_n_u16(uint16_t value)


vmov 함수

uint16x8_t r = vmovq_n_u16(uint16_t value)


두 함수는 명칭만 다를뿐 수행 기능은 같다.

예) value 값을 벡터 r의 모든 레인에 대입한다.


2. NEON 레인 조회

레인 조회에 관련된 함수는 레인의 값만 확인하는 것이 아니라, 두 벡터의 레인으로 하나의 새로운 벡터를 

생성하거나 레인을 조합하여 새로운 벡터를 생성할 수 있다. 


2.1 레인 조회 함수

레인 번호가 저장된 벡터를 이용하여 대상 벡터의 레인 값을 조회하고, 조회된 값으로 새로운 벡터를 생성한다. 

레인 조회 함수는 단일 벡터와 복수 벡터를 모두 조회할 수 있다.

벡터 변수 조회는 8bit 레인 더블 워드 벡터에서만 동작하고, 조회의 범위를 벗어나면 0을 저장한다.


2.1.1 단일 벡터 레인 조회

int8x8_t r = vtbl1_s8(int8x8_t a, int8x8_t b)


벡터 b의 레인에는 벡터 a에서 가져올 레인의 번호가 저장된다. 예를 들어 벡터 b의 0번 레인에 4가 대입되어 있다면,

벡터a의 4번 레인의 값 5를 벡터 r의 0번 레인에 저장한다. 벡터 a, b, r의 크기는 모두 같아야 하며, 벡터 b는

8bit 더블레인 워드벡터여야만 한다. 

벡터 b와 같이 조회하는 레인 번호를 가진 벡터를 테이블 벡터 또는 테이블이라고 한다.


2.1.2 복수 벡터 레인 조회

int8x8_t r = vtbl2_s8(int8x8x2_t a, int8x8_t b)


단일 벡터 레인 조회방법과 동일하게 벡터 a 레인값을 벡터 b에 있는 레인 번호를 이용하여 조회하고, 

결과를 벡터 r에 저장한다. 조회범위가 벗어나면 0을 저장한다. 

복수 벡터 a의 레인은 val[0]과 val[1]이 각각 0번 레인부터 시작하지 않고, val[0]의 0번 레인부터 차례로

증가해서 val[1]의 마지막 레인이 15번 레인이 된다.


2.2 레인 조회 확장 함수

레인 조회 확장 함수도 레인 번호가 저장된 벡터를 이용하여 대상 벡터의 레인 값을 조회하고,

조회된 값을 새로운 벡터에 저장한다. 레인 조회 확장 함수는 레인 조회 함수와 다르게 조회된 범위를

벗어나면 0을 저장하지 않고, 또 다른 벡터의 레인 값으로 저장한다.


int8x8_t r = vtbx1_s8(int8x8_t a, int8x8_t b, int8x8_t c)


벡터 c에 있는 레인 번호를 이용해서 벡터 b의 레인 값을 조회하고, 결과를 벡터 r에 저장한다. 

만약 조회의 범위가 벗어나면 벡터 a의 레인 값으로 대체한다. 

(확장함수와 기본 조회함수와의 차이를 주의해야 한다. 벡터 조회에서는 벡터 b가 테이블 벡터이지만,

벡터 조회 확장에서는 벡터 c가 테이블 벡터가 된다.)


2.3 레인 조합 함수

두 벡터의 레인을 조합하여 하나의 벡터로 생성한다.

int8x8_t r = vext_s8(int8x8_t a, int8x8_t b, __constrange(0, 7) int c)


변수 c의 값을 이용해서 벡터 a와 b의 레인을 조합하여, 그 결과를 벡터 r에 대입한다. 

레인 조합은 피연산자 벡터 a의 7번 레인에서부터, 두 번째 피연산자 벡터 b의 0번 레인에서부터 레인을 추출한다.

예를 들면 c가 3일때 b벡터 3개 a벡터 5개를 추출해 저장한다.


2.4 레인 교환 함수

하나의 벡터 변수 안에서 레인의 값을 교환(Swap)할 수 있다. 레인 교환 함수는 여러가지 종류가 있는데,

함수의 이름으로 교환되는 벡터의 범위와 레인의 크기를 예측할 수 있다.

n비트의 크기에 따라 총 3가지 유형의 레인 교환 함수가 있다.

더블 워드 내 레인 교환

싱글 워드 내 레인 교환

하프 워드 내 레인 교환


2.4.1 더블 워드 내 레인 교환

int8x8_t r = vrev64_s8(int8x8_t vec)

벡터 내에서 더블 워드 크기로 레인의 순서를 교환하고 결과를 벡터 변수에 저장한다.

0번 레인은 7번 레인, 1번 레인은 6번 레인, 2번 레인은 5번 레인, 3번 레인은 4번 레인 순으로 교환해 저장한다.


2.4.2 싱글 워드 내 레인 교환

int8x8_t r = vrev32_s8(int8x8_t vec)

벡터 내에서 싱글 워드 크기로 레인의 순서를 교환하고 결과를 벡터 변수에 저장한다.

0번 레인은 3번 레인, 3번 레인은 0번 레인과 같이 하나의 벡터 변수를 두 개(절반)로 나눠서 레인 교환한다.

4번 레인은 7번 레인, 7번 레인은 4번 레인


2.4.3 하프 워드 내 레인 교환

int8x8_t r = vrev16_s8(int8x8_t vec)

벡터 내에서 하프 워드 크기로 레인의 순서를 교환하고 결과를 벡터 변수에 저장한다.

0번 레인은 1번 레인, 1번 레인은 0번 레인과 같이 하나의 벡터 변수를 네개로 나눠서 레인 교환한다.

(서로 인접해 있는 것끼리 교환)

'Programming > NEON' 카테고리의 다른 글

[NEON] 비교 연산과 절대값  (0) 2016.09.23
[NEON] 비트와 시프트 연산  (0) 2016.09.23
[NEON 산술 연산과 확장  (0) 2016.09.23
[NEON] 함수 정리 (로드 함수, 저장 함수)  (0) 2016.09.23
[NEON] 벡터 자료형  (0) 2016.09.23