2016-09-19 3 views
0

Im ARM 및 NEON 프로그래밍에 상당히 새로운 점은 SAD (Sum of Absolute Difference) 기능을 최적화하는 작업이 주어 졌기 때문입니다. 어디에서 시작해야할지 모르겠다. 성공하지 않고 NEON 코드를 생성하는 몇 가지 방법을 시도했다.ARM NEON 8x8 SAD 연산

void sad_block_8x8(uint8_t *block1, uint8_t *block2, int stride, int *result) 
{ 
    int u, v; 

    *result = 0; 

    for (v = 0; v < 8; ++v) 
    { 
     for (u = 0; u < 8; ++u) 
     { 
      *result += abs(block2[v*stride+u] - block1[v*stride+u]); 
     } 
    } 
} 

그래서 내 문제는 다음과 같습니다 :

  1. 어떻게 내가 계산을 어떻게마다 반복
  2. 에 대한 레지스터를로드하고 변수에 결과를 저장 할 순차 함수는 다음과 같이 보입니다

도움이 될 것입니다!

좋아는 ... 그래서 내 첫 번째 시도는 다음과 같이이었다 (작동하지만, 나는 매우 나쁜 네온 코드 알고)

void sad_block_8x8_2(uint8_t *block1, uint8_t *block2, int stride, int *result) 
{ 
int u, v; 
uint8x8_t m_1, m_2, m_o; 
uint8_t* test; 
test = (uint8_t*)malloc(v*u*sizeof(uint8_t));; 
*result = 0; 
for (v = 0; v < 8; ++v) 
{ 
    for(u = 0; u < 8; ++u) 
    { 
     m_1 = vld1_u8(&block1[v*stride]); 
     m_2 = vld1_u8(&block2[v*stride]); 

     m_o = vabd_u8(m_2, m_1); 
     vst1_u8(&test[v], m_o); 
     //printf("%d ", test[v]); 
     *result += (int)test[v]; 
    } 
} 
} 

어떤 도움하세요?

+1

입력 데이터 블록은'const'이어야합니다. 자동 벡터화 할 수있는 NEON 가능 컴파일러를 사용해 보셨습니까? – unwind

+0

8x8 ~ 8x1을 얻으려면 arm_neon.h에서'uint16x8_t vabal_u8 (uint16x8_t, uint8x8_t, uint8x8_t)'을 사용할 수 있습니다 – user3528438

답변

0

이 당신이 원하는 SAD 알고리즘의 좀 더 명확 구현은 다음과 같습니다

void neon_sad_block_8x8(uint8_t *__restrict block1, uint8_t * __restrict block2, int stride, int *__restrict result) 
{ 
     int i, j; 
     uint8x8_t neon_block1; 
     uint8x8_t neon_block2; 
     uint8x8_t res; 
     int sum = 0; 
     for (i = 0; i < 8; i++) {             
      neon_block1 = vld1_u8(&block1[i * stride]);      
      neon_block2 = vld1_u8(&block2[i * stride]);      
      res = vabd_u8(neon_block2, neon_block1);       
      sum += res[0] + res[1] + res[2] + res[3] + res[4] + res[5] + res[6] + res[7]; 
     } 
     *result = sum; 
} 

이 코드가 있습니다

  • 하나 개의 루프
  • 루프
  • 에는 휴식 문이 없습니다
  • 포인터는 __restrict에 의해 보호됩니다.
+0

uint8x8_t 유형의 간단한 배열로 정의 된 uint8x8x4_t와 같은 벡터 데이터 유형을 사용할 수도 있습니다 : typedef struct int8x8x4_t { int8x8_t val [4]; } int8x8x4_t; – nachiketkulk

+0

64 비트 아키텍처에서 코드를 실행하는 경우 uint8_t vaddvq_u8() 함수를 사용하여 하나의 명령어에서 레인의 모든 요소를 ​​추가 할 수 있습니다. – nachiketkulk

관련 문제