2012-12-04 2 views
4

C++ 코드의 NEON 내장 함수를 사용하여 ARM 최적화 작업을하고 있습니다. 나는 타이핑 문제의 대부분을 이해하고 마스터하지만,이 문제에 집착하고있다 :NEON 내장 함수와 데이터 유형 호환성

vzip_u8 명령어는 uint8x8x2_t 값 (실제로는 2 개의 배열 uint8x8_t)을 반환한다. 반환 된 값을 일반 uint16x8_t에 할당하려고합니다. 이를 달성하기 위해 본질적으로 적절한 vreinterpretq이 보이지 않으며 간단한 캐스트가 거부됩니다.

+0

. 그러나 아직도 어떻게 개조 할 것인지 전혀 모른다. –

+0

작은 스 니펫을 게시하여 질문을 보여줄 수 있습니까? – auselen

답변

1

나는 val 유형의 val 구성원이 배열이므로 배열로 간주되므로 해결 방법을 발견했습니다. 캐스팅 및 캡쳐 해제가 작동합니다! [데이터의 주소를 복용 경고에 "임시 주소"를 제기 반면.]

uint16x8_t Value= *(uint16x8_t*)vzip_u8(arg0, arg1).val; 

이것이 컴파일 (적어도 경우 I을 시도) 정상적으로 실행하는 것이 밝혀졌다. 어셈블리 코드를 보지 않아서 제대로 구현되지 않았다. (메모리에 쓰거나 읽는 대신 레지스터에 값을 저장하는 것을 의미한다.)

+1

왜 그들이 그렇게 제약하게 만들 었는지 말해주는 사람은 누구나 ... 환영합니다. –

+0

[내 대답] (http://stackoverflow.com/a/29229662/2436175)을 보시오. – Antonio

+0

나는 전문가는 아니지만 나는 그렇게 생각한다. [엄격한 앨리어싱 규칙을 위반합니다] (http://stackoverflow.com/a/29253236/2436175). 벡터의 두 벡터가 동일한 128 비트 레지스터에 결합되어 있지 않은 위험도 [auselan에 의해 언급 됨] (http://stackoverflow.com/a/13734838/2436175). – Antonio

5

명확하게 대답 할 정의가있다.

NEON은 64 비트 폭 (16 비트 레지스터로서 128 비트 폭)의 32 레지스터를 갖는다.

  • 여섯 128- 비트 쿼드 워드 레지스터, Q0-Q15
  • 서른 두 레지스터 더블 64 비트 D0-D31 :

    네온 유닛은 상기와 같은 레지스터 뱅크를 볼 수 .

    uint16x8_t

는 그것이 quadword 레지스터에 있어야하므로 128 비트 저장을 필요로하는 타입이다.

ARM 네온 내장 함수 ARM® C Language Extensionsvector array data type라고 정의 가지고 테이블 룩업 동작에

...로드 및 저장 동작의 사용을, 및 동작의 결과 유형으로 그 한 쌍의 벡터를 반환합니다.

vzip 명령

...는 두 벡터의 요소들을 인터리빙한다.VZIP 지침 아무튼 때문에

VZIP DD, DM

하고, 우리가 uint8x8x2_t 실제로이 개 임의 번호가 더블 레지스터의 목록입니다 결론을 내릴 수있는 intrinsic이에서

uint8x8x2_t vzip_u8 (uint8x8_t, uint8x8_t) 

같은있다 입력 레지스터의 순서에 대한 요구 사항이 없습니다.

이제 답 uint16x8_t 처음 하나 (D0-D31 짝수 인덱스를 갖는 두 개의 연속 dualword 레지스터로 구성된 데이터 구조 인 반면

uint8x8x2_t 비 연속적인 두 dualword 레지스터를 포함 할 수 ... 인 -> Q0 -Q15).

이 때문에 두 개의 더블 워드 레지스터가있는 vector array data type을 쿼드 워드 레지스터에 쉽게 캐스팅 할 수 없습니다.

컴파일러가 도움이 될 정도로 스마트하거나 변환을 강제 할 수는 있지만 결과 어셈블리의 성능과 정확성을 검사합니다.

+0

이제 모든 것이 더 명확 해졌습니다. uint8x8x2_t는 비 연속적인 데이터를 설명하기 때문에 "의사 유형"이어야합니다. 그러나 나의 초기 질문은 남아있다 : ​​"당신은 단지 변환을 강제 할 수있다". 어떻게? ??? –

+0

하지만 내가 말했듯이, 컴파일러는이를 해결할 수 있습니다. 성능 문제가 발생할 수 있습니다. 바이너리를 확인해야합니다. – auselen

+0

제 문제는 컴파일러가 캐스트를 허용하는 방법을 찾지 못했습니다. –

-1

4.5 및 4.6 시리즈의 GCC (현재 수정 됨)에 버그가 있습니다.

버그질라 링크 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48252

이 버그에서 수정을하고 GCC 소스에 적용하고 재 구축하십시오.

+0

안녕하세요. 이 게시물에 공헌 해 주셔서 감사합니다. 컴파일러의 코드 생성 버그가 아니라 구문/의미 비 호환성 문제 인 현재 문제는 다루지 않습니다. –

4

vcombine_ * 내장 함수를 사용하여 두 개의 64 비트 벡터에서 128 비트 벡터를 구성 할 수 있습니다. 따라서, 당신은 당신이 원하는 것을 얻을 수 있습니다.

#include <arm_neon.h> 

uint8x16_t f(uint8x8_t a, uint8x8_t b) 
{ 
    uint8x8x2_t tmp = vzip_u8(a,b); 
    uint8x16_t result; 
    result = vcombine_u8(tmp.val[0], tmp.val[1]); 
    return result; 
} 
+0

흥미 롭습니다. 감사합니다. 나는 그것을 조사 할 것이다. (그러나 아마 곧, 이것은 잠자는 프로젝트이다.) –

0

저는 같은 종류의 문제에 직면 했으므로 a flexible data type을 소개했습니다. 나는 그러므로 이제 다음을 정의 할 수 있습니다

:

그냥 uint8x8x2_t는 "벡터 배열 데이터 유형"이라고 수동에서 발견
typedef NeonVectorType<uint8x16_t> uint_128bit_t; //suitable for uint8x16_t, uint8x8x2_t, uint32x4_t, etc. 
typedef NeonVectorType<uint8x8_t> uint_64bit_t; //suitable for uint8x8_t, uint32x2_t, etc. 
관련 문제