빠른 구석 최적화를 계속하기로 결정하고 _mm_movemask_epi8
SSE 명령에 밀착되었습니다. uint8x16_t
입력으로 ARM Neon에서 어떻게 다시 쓸 수 있습니까? 나는이 중 하나를 테스트하지 않은,하지만 이런 식으로 뭔가가 작동 할 수SSE _mm_movemask_epi8 해당 메소드 for ARM NEON
5
A
답변
0
올바른 작동 :
int32_t _mm_movemask_epi8_neon(uint8x16_t input)
{
const int8_t __attribute__ ((aligned (16))) xr[8] = {-7,-6,-5,-4,-3,-2,-1,0};
uint8x8_t mask_and = vdup_n_u8(0x80);
int8x8_t mask_shift = vld1_s8(xr);
uint8x8_t lo = vget_low_u8(input);
uint8x8_t hi = vget_high_u8(input);
lo = vand_u8(lo, mask_and);
lo = vshl_u8(lo, mask_shift);
hi = vand_u8(hi, mask_and);
hi = vshl_u8(hi, mask_shift);
lo = vpadd_u8(lo,lo);
lo = vpadd_u8(lo,lo);
lo = vpadd_u8(lo,lo);
hi = vpadd_u8(hi,hi);
hi = vpadd_u8(hi,hi);
hi = vpadd_u8(hi,hi);
return ((hi[0] << 8) | (lo[0] & 0xFF));
}
0
참고 : vpadd
는 64 일부터
X := the vector that you want to create the mask from
A := 0x808080808080...
B := 0x00FFFEFDFCFB... (i.e. 0,-1,-2,-3,...)
X = vand_u8(X, A); // Keep d7 of each byte in X
X = vshl_u8(X, B); // X[7]>>=0; X[6]>>=1; X[5]>>=2; ...
// Each byte of X now contains its msb shifted 7-N bits to the right, where N
// is the byte index.
// Do 3 pairwise adds in order to pack all these into X[0]
X = vpadd_u8(X, X);
X = vpadd_u8(X, X);
X = vpadd_u8(X, X);
// X[0] should now contain the mask. Clear the remaining bytes if necessary
이, 128 비트 벡터를 처리하기 위해 한 번 반복 될 필요가있을 것이다 비트 벡터. 이 코드를 다음과 같은 몇 가지 테스트 후
5
이 게시물은 매우 오래된 알고 있지만 나는 그것이 유용 내 (검증) 솔루션을 제공하는 발견했다. 그것은 Input 인수의 모든 레인에서 모두 1/모두 0으로 가정합니다. (어쨌든 마음 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47553.)
const uint8_t __attribute__ ((aligned (16))) _Powers[16]=
{ 1, 2, 4, 8, 16, 32, 64, 128, 1, 2, 4, 8, 16, 32, 64, 128 };
// Set the powers of 2 (do it once for all, if applicable)
uint8x16_t Powers= vld1q_u8(_Powers);
// Compute the mask from the input
uint64x2_t Mask= vpaddlq_u32(vpaddlq_u16(vpaddlq_u8(vandq_u8(Input, Powers))));
// Get the resulting bytes
uint16_t Output;
vst1q_lane_u8((uint8_t*)&Output + 0, (uint8x16_t)Mask, 0);
vst1q_lane_u8((uint8_t*)&Output + 1, (uint8x16_t)Mask, 8);
마찬가지로 마이클, 트릭은 null이 아닌 항목의 인덱스의 힘을 형성하고 세 번 쌍으로 요약하는 것입니다. 이는 추가 할 때마다 스트라이드를 두 배로 늘리려면 데이터 크기를 늘려야합니다. 2 x 8 8 비트 항목에서 2 x 4 16 비트, 2 x 2 32 비트 및 2 x 1 64 비트로 줄입니다. 이 두 숫자 중 낮은 바이트가 해결책을 제공합니다. NEON을 사용하여 단 하나의 짧은 값을 구성하기 위해 함께 패킹하는 쉬운 방법은 없다고 생각합니다.
입력이 적절한 형식이고 전원을 사전로드 할 수있는 경우 NEON 명령을 6 회 수행합니다.
관련 문제
- 1. 빠른 ARM NEON memcpy
- 2. 비디오 형식 변환을위한 ARM-NEON
- 3. ARM 어셈블러 NEON - 성능 향상
- 4. NEON 대 Intel SSE - 특정 작업과 동일합니다.
- 5. 레거시 어셈블리에서 ARM NEON 명령어 사용
- 6. ARM NEON : 어떤 명령어 쌍이 후 기록을 기다려야합니까? 는 ARM NEON 문서에서
- 7. Android 용 ARM NEON 디버깅 NDK
- 8. ARM NEON : 128 비트 값 비교
- 9. ARM NEON 색인을 사용하여 값을 변경하는 방법
- 10. ARM NEON Visual Studio의 Intrisics 지원
- 11. ARM Neon 어셈블러 - 이상한 파이프 라인 문제
- 12. flex for ARM 컴파일 -?
- 13. ARM Neon 내장 함수에 대한 좋은 참고 자료가 있습니까?
- 14. ARM NEON 용 xor gcc 내장 함수 없음
- 15. Intrinsics Vs 인라인 ASM for SSE for VC++ 2K8
- 16. SSE2를 Arm NEON으로 마이그레이션하십시오. intrinsincs
- 17. NEON 벡터 데이터 형식의 별칭
- 18. ARM-NEON은 어떻게 동기화합니까?
- 19. 설치 Visual Studio express for arm
- 20. ARM memcpy 및 정렬
- 21. 코드를 Neon 어셈블리로 변환하십시오.
- 22. NEON 내장 함수와 데이터 유형 호환성
- 23. Java에서 해당 메소드 내에서 메소드 이름을 찾는 방법은 무엇입니까?
- 24. Really basic SSE
- 25. Android 앱 - 해당 메소드 예외 없음
- 26. SSE 내장 함수에 해당하는 네온
- 27. SSE 명령에서 오류가 발생했습니다
- 28. SSE 버전이 다른 결과
- 29. Android에서 ffmpeg 빌드. NEON (Tegra3) 및 Cygwin 사용
- 30. SSE 액세스 위반
안녕하세요 @Michael thanx 예입니다. 어떻게하면 벡터 B를 필요한 바이트로 채울 수 설명 할 수 있습니까? A는 vdup_n_u8 (0x80)을 사용할 수 있지만 A는 어떻게해야합니까? 또한 u는 vshl_u8을 작성하지만 주석에는 시프트가 올바르게 있습니까? – inspirit
const 배열 (?)에서 벡터 B :'vld1'을 초기화합니다. 오른쪽 시프트에 대한 정보 : ARM 설명서에서 "시프트 값이 양수이면 왼쪽 시프트이고 그렇지 않으면 오른쪽 시프트입니다." 나는 여러분이 이동하는 데이터가'u8'이거나's8'을 사용해야 할 필요가 있는지 완전히 확신하지 못합니다. – Michael
옙 나는 배열에서 B를로드해야한다는 것을 알고있다. 나는 그 벡터에서 제공된 값에 대해 궁금해했다. 그것에 대해 더 구체적으로 설명해 줄 수 있습니까? 그냥 [0, -1, -2, -3, -4, -5, -6, -7]이어야합니까? 그리고 예, 순간에 u8 데이터 벡터가 필요합니다 – inspirit