2017-02-24 21 views
1

AVX2 벡터를 상수로 나누고 싶습니다. 나는 this question과 많은 다른 페이지들을 방문했다. 도움이 될만한 무엇인가를 보니 Fixed-point arithmetic와 나는 이해하지 못했다. 그래서 문제는이 부서가 병목입니다. I는 두 가지 시도 :__m256i 벡터를 정수 변수로 나누는 방법은 무엇입니까?

먼저 플로트와 AVX 명령으로 동작 할 캐스팅 : 첫번째 방법에서는

//outside the bottleneck: 
__m256i veci16; // containing some integer numbers (16x16-bit numbers) 
__m256 div_v = _mm256_set1_ps(div); 

//inside the bottlneck 
//some calculations which make veci16 
vecps = _mm256_castsi256_ps (veci16); 
vecps = _mm256_div_ps (vecps, div_v); 
veci16 = _mm256_castps_si256 (vecps); 
_mm256_storeu_si256((__m256i *)&output[i][j], veci16); 

문제는 다음 분할 시간은 나노초이며,이 경과 시간은으로 경과하지 약 60ns.

둘째, 나는 배열에 저장이처럼로드 :

int t[16] ; 
inline __m256i _mm256_div_epi16 (__m256i a , int b){ 

    _mm256_store_si256((__m256i *)&t[0] , a); 
    t[0]/=b; t[1]/=b; t[2]/=b; t[3]/=b; t[4]/=b; t[5]/=b; t[6]/=b; t[7]/=b; 
    t[8]/=b; t[9]/=b; t[10]/=b; t[11]/=b; t[12]/=b; t[13]/=b; t[14]/=b; t[15]/=b; 
    return _mm256_load_si256((__m256i *)&t[0]);   
} 

를 글쎄, 더 나은했다. 그러나 아직 경과 된 시간은 17ns입니다. 계산은 너무 많이 여기에 표시됩니다.

질문 :이 인라인 함수를 더 빠르게 최적화 할 수있는 방법이 있습니까?

+0

왜 투표가 내려 집니까? – Martin

+1

내 투표가 아니지만 ['_mm256_mulhrs_epi16'] (https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm256_mul&expand=3710)을 원할 수도 있습니다. 이것은 고정 소수점 곱셈을합니다. 그래서 여러분은 단지 피승수 벡터를'32768/b'로 설정합니다. –

+0

곱셈입니다. 나는 그것을 나누고 싶다. – Martin

답변

4

_mm256_mulhrs_epi16으로이 작업을 수행 할 수 있습니다. 이것은 당신이 단지 32768/b에 피승수 벡터를 설정하므로, 고정 소수점 곱셈을 수행이 b > 1 가정

inline __m256i _mm256_div_epi16 (const __m256i va, const int b) 
{ 
    __m256i vb = _mm256_set1_epi16(32768/b); 
    return _mm256_mulhrs_epi16(va, vb); 
} 

하는 것으로.

+1

이 대답은 놀랍습니다. 위반이없는 것은 5 초입니다. – Martin