F.1. 소개

ARM® 컴파일러에서는 NEON Intrinsic을 사용하여 컴파일러 벡터화 단계와 어셈블러 코드 작성 단계 사이에서 SIMD 코드를 생성하는 중간 단계를 사용할 수 있습니다. 이 기능을 사용하면 어셈블러를 직접 작성할 때보다 NEON 아키텍처를 사용하는 코드를 더 쉽게 작성할 수 있습니다.

이 부록에서 설명하는 intrinsic은 ARMv7 아키텍처의 NEON 명령어와 밀접하게 연관되어 있습니다. 각 섹션은 동등한 어셈블러 명령어를 지정하는 주석을 가진 함수 프로토타입 목록으로 시작됩니다. 컴파일러가 필요한 의미를 가진 명령어를 선택하지만 반드시 목록에 있는 명령어를 내보낸다는 보장은 없습니다.

ARMv7 이전 아키텍처에서는 NEON intrinsic을 지원하지 않습니다. 이전 아키텍처나 NEON이 포함되지 않은 ARMv7 아키텍처 프로파일에 대해 빌드하는 경우 컴파일러는 NEON Intrinsic을 일반 함수 호출로 처리합니다. 따라서, 링크 타임에 오류가 발생합니다.

NEON에 대한 자세한 내용은 RealView Compilation Tools 버전 3.0 핵심 설명서를 참조하십시오.

이 부록에서 설명하는 NEON intrinsic은 arm_neon.h 헤더 파일에 정의됩니다. 헤더 파일은 intrinsic과 벡터 타입 세트를 모두 정의합니다. 자세한 내용은 install_directory\Documentation\Specifications의 ARM DAI 0156A: Using Neon Intrinsics with RVDS 3.0을 참조하십시오.

Example F.1에서 NEON intrinsic을 사용하는 간단한 예를 보여줍니다. 예제를 빌드하려면

  1. 다음 옵션을 지정하여 C 파일을 컴파일합니다.

    armcc -c --debug --cpu Cortex-A8 neon_example.c
    
  2. 다음 명령을 사용하여 이미지를 링크합니다.

    armlink neon_example.o -o neon_example.axf 
    
  3. 호환되는 디버거, 예를 들어 RealView Debugger를 사용하여 이미지를 로드하고 실행합니다.

Example F.1.  NEON intrinsic

/* neon_example.c - Neon intrinsics example program */
#include <stdint.h>
#include <stdio.h>
#include <assert.h>
#include <arm_neon.h>

/* fill array with increasing integers beginning with 0 */
void fill_array(int16_t *array, int size)
{    int i;
    for (i = 0; i < size; i++)
    {
         array[i] = i;
     }
}

/* return the sum of all elements in an array. This works by calculating 4 totals (one for each lane) and adding those at the end to get the final total */
int sum_array(int16_t *array, int size)
{
     /* initialise the accumulator vector to zero */
     int16x4_t acc = vdup_n_s16(0);
     int32x2_t acc1;
     int64x1_t acc2;

     /* this implementation assumes the size of the array is a multiple of 4 */
     assert((size % 4) == 0);

     /* counting backwards gives better code */
     for (; size !=0; size -= 4)
     {
          int16x4_t vec;
          /* load 4 values in parallel from the array */
          vec = vld1_s16(array);
          /* increment the array pointer to the next element */
          array += 4;
          /* add the vector to the accumulator vector */
          acc = vadd_s16(acc, vec);
      }
      /* calculate the total */
      acc1 = vpaddl_s16(acc);
      acc2 = vpaddl_s32(acc1);

      /* return the total as an integer */
      return (int)vget_lane_s64(acc2, 0);
}

/* main function */
int main()
{
      int16_t my_array[100];

      fill_array(my_array, 100);
      printf("Sum was %d\n", sum_array(my_array, 100));

      return 0;
}
Copyright © 2002-2006 ARM Limited. All rights reserved.ARM DUI 0205GK
Non-Confidential