2016-08-31 14 views
0

일부 C 코드에서 AVX2 명령어를 사용하고 있습니다.소스 기반 인덱스에서 대상 기반 인덱스로 변환

VPERMDidx 명령에 기초 a를 뮤팅하여, 2 개의 8 정수 및 벡터 aidx 소요 세번째, dst를 생성한다. 이것은 dst[i] = a[idx[i]] for i in 0..7과 같습니다. 이 소스는 소스를 기반으로 인덱싱되므로 소스 기반이라고합니다.

그러나 계산 된 색인은 대상 기반 양식에 있습니다. 배열을 설정하는 것은 당연한 것이며 dst[idx[i]] = a[i] for i in 0..7과 같습니다.

발신지 기반 양식을 대상 기반 양식으로 변환하려면 어떻게해야합니까? 예 테스트 케이스는이 변환

{2 1 0 5 3 4 6 7} source-based form. 
{2 1 0 4 5 3 6 7} destination-based equivalent 

, 내가 YMM 레지스터에 머물고있어, 그 목적지 기반의 솔루션이 작동하지 않는 것을 의미하므로. 각각을 개별적으로 삽입하더라도 상수 인덱스에서만 작동하기 때문에 설정할 수는 없습니다.

+1

그건 그냥 고전적인 "순열 역전",'dst [src] = i' – harold

+0

맞아. 하지만 코드에는 대상 기반 방식으로 설정할 수있는 기능이 필요합니다. AVX2 레지스터에서 작동하고 있기 때문에. 나는 그것을 할 수 없다. 나는 당신이 말한 것과 거의 똑같은 C 코드를 가지고 있지만, 당신이 제안한 것처럼 목적지 기반 순열을 수행 할 수 없어도 인덱스를 변환 할 수 있어야합니다. – eyepatch

+0

'a [i] = a [idx [i]] for i가 0..7이면,'a [i] = a [idx [i]]는 VPERMD의 연산을 정확하게 표현하지 못했습니다. i]]'를 사용한다. 예 : 'idx [0] = 0'이 아닌 한 원래의'a [0]'은 즉시 파괴됩니다. 나는 그 버그를 바로 잡기 위해 당신의 예가 제정신이 아니었다 고 생각합니다. (또는 그 행동을 전체 시간으로 가정하고있었습니다.) –

답변

2

처음에는 소스 기반 인덱스를 계산하도록 코드를 수정할 수 없다고 말한 것 같습니다. dst 기반 인덱스를 사용하는 AVX512 분산 명령어 이외에 x86 SIMD로 할 수있는 일은 생각할 수 없습니다.

벡터를 메모리에 저장, 반전 및 다시로드하는 것이 실제로 가장 효과적 일 수 있습니다. (또는 메모리를 통하지 않고 정수 레지스터로 직접 전송할 수도 있습니다. 따라서 vextracti128/packusdw 다음에 벡터에서 정수 regs : movq 및 pextrq 두 개의 64 비트 전송 만 필요합니다.

하지만 어쨌든 색인으로 사용하여 카운터를 메모리의 배열에 저장하고이를 벡터로 다시로드하십시오. 이것은 여전히 ​​느리고 추악하며 매장 전달 실패 지연을 포함합니다. 따라서 인덱스 생성 코드를 변경하여 소스 기반 셔플 벡터를 생성하는 것이 좋습니다.