2011-09-26 3 views
1

SSE2 intrinsincs에 다음 코드가 있습니다. Kinect의 입력을 처리합니다. SSE2를 Arm NEON으로 마이그레이션하십시오. intrinsincs

__m128i md = _mm_setr_epi16((r0<<3) | (r1>>5), ((r1<<6) | (r2>>2)), ((r2<<9) | (r3<<1) | (r4>>7)), ((r4<<4) | (r5>>4)), ((r5<<7) | (r6>>1)),((r6<<10) | (r7<<2) | (r8>>6)), ((r8<<5) | (r9>>3)), ((r9<<8) | (r10) )); 
md = _mm_and_si128(md, mmask); 
__m128i mz = _mm_load_si128((__m128i *) &depth_ref_z[i]); 
__m128i mZ = _mm_load_si128((__m128i *) &depth_ref_Z[i]); 
mz = _mm_cmpgt_epi16(md, mz); 
mZ = _mm_cmpgt_epi16(mZ, md); 
mz = _mm_and_si128(mz, mZ); 
md = _mm_and_si128(mz, md); 
_mm_store_si128((__m128i *) frame,md) 
if(_mm_movemask_epi8(mz)){ ... } 

는 기본적 SSE 레지스터 8 uint16_t 11 uint8_t (R0-R10)를 언팩 (mmask 일정 이전에 생성된다). 그런 다음 경계로 사용되는 두 개의 배열에서 해당 요소가있는 두 개의 레지스터를 추가로로드합니다. 그것들을 검사하고 제로 아웃 된 기준에 맞지 않는 요소를 가진 레지스터를 만듭니다. 그런 다음이를 저장하고 각 요소를 추가로 처리합니다. movemask는 엘리먼트 중 어느 것도 통과하지 못했을 때 좋은 최적화로 사용되며, 어떤 경우에는 처리를 건너 뛸 수 있습니다.

이것은 훌륭하게 작동하며 이제는 NEON으로 포팅하려고합니다. 대부분은 두 부분을 제외하고는 간단합니다. SSE2 코드에서 어셈블러 출력 (gcc)을 보면 _mm_setr_epi16에서 8 개의 uint16_t 이동을 수행하는 대신 uint32_t로 이동할 수 있고 마지막으로 4 개의 이동을 수행한다는 것을 알 수 있습니다. 효율적인 것으로 보이고 컴파일러가 처리하므로 코드를 변경하지 않았습니다. NEON 경우 수동으로 적용해야합니까? 대신 8 vsetq_lane_u16 이동 및 수행 4 vsetq_lane_u32? 나는 endianess에 어떤 문제가있을 것이고 그것은 보람있을 것입니까?

최종 부품은 동급 제품을 찾을 수 없어서 이동 마스크입니다. 누구든지 뭔가 제안 할 수 있습니까?

답변

1

나는 SSE2 대신 일반 C 코드로 시작하는 것을 선호합니다. 이 낮은 수준에서 쉽게 볼 수없는 최적화 기회가있을 수 있습니다.