2017-10-27 39 views
2

AVX (ARM NEON에서 제공)를 처음 접했고 AVX에 많은 U8 산술이 부족하다는 사실에 놀라움을 금치 못했습니다. AVX2 : U8의 절대적인 차이

는 그러므로 나는 인라인 함수와 max(a,b)-min(a,b)에 의지했다 :

static inline __m256i _mm256_abd_epu8(__m256i a, __m256i b) 
{ 
    return _mm256_sub_epi8(_mm256_max_epu8(a, b), _mm256_min_epu8(a, b)); 
} 

나는이 문제를 다루는보다 효율적인 방법이 있는지 궁금합니다.

예, 저는 _mm256_sad_epu8을 알고 있지만 그 차이가 필요합니다. 합계가 아닙니다.

모든 입력을 주시면 감사하겠습니다. 이전 버전과의 호환성을 무시하고 AVX2으로 확인하십시오.

미리 감사드립니다.

답변

5

2 개 이하의 명령어로이 작업을 수행하는 트릭을 인식하지 못했습니다. (그리고이 질문의 SSE 버전은 더 좋은 것을 가지고 있지 않습니다 : Compute the absolute difference between unsigned integers using SSE). 이 답변에서 사용한 포화 메서드를 언급합니다.


사전 스카이 레이크에 약간 더 나은 : 서명 후 채도, 또는 결과에 두 가지를 뺍니다. (각 요소 제로 어느 AB 또는 BA 포화된다.)

스웰에서 _mm256_or_si256(_mm256_subs_epu8(a,b), _mm256_subs_epu8(b,a))

/pmaxpminpsub 단지 포트 1 포트 (5)에서 실행되지만 por 세 개의 벡터 실행 중 실행할 수 포트 (0, 1, 5).

Skylake는 3 번째 벡터 정수 덧셈기를 추가하므로 그 uarch에는 차이가 없습니다.

이 또한 VPOR은 P0123의에서 실행할 수 Ryzen에 약간 더 (. 인텔의 최적화 설명서를 포함하여 태그 위키 http://agner.org/optimize/ 및 기타 링크를 참조하십시오), 그러나 PADD/PMIN 단지에 따라 P013에서 실행할 수 있습니다 Agner Fog의 테스트. (Ryzen은 256b 벡터 연산을 2 uops로 분할하지만 유용하기 때문에 처리량이 있습니다. 단일 uop 명령어 만 사용하여 6-uop 와이드 파이프를 채울 수 없습니다.)

포트는 할당 된 포트를 기다리는 데 지연 될 가능성이 적기 때문에 (리소스 충돌), 실제로이 작업을 통해 2 사이클의 총 대기 시간을 확보 할 수 있습니다 (두 입력이 모두 준비되어 출력 준비가 준비 됨). 또한 특정 포트 (Intel Has Hasle 이상에서 유일한 셔플 유닛이있는 포트 5와 같은)에 대한 경쟁이있을 경우 처리량 병목 현상에 기여할 가능성이 적습니다.

+0

와우, 나는 더 포괄적 인 대답을 상상조차 할 수 없다. 정확히 내가 필요로하는 것. 고맙습니다. –

+0

@ Jake'Alquimista'LEE : 건배, 당신이 마이크로 아키텍쳐를 좋아할 거라 생각 했으니 까. –

+0

절대적으로 !!!! 이제 저는 파이프 라인을 더 깊이 파야한다는 것을 알고 있습니다. 당신이 준 링크는 신의 선물입니다. –