2017-03-06 10 views
0

설명서에 따르면 AVX-512 명령어 세트의 gcc 4.9에서 지원되지만 gcc 4.8이 있습니다. 우리가있는 경우 네, 말, 문서를 통해보고, 이제AVX-512 마스크 시뮬레이션 지침

__mm128i sum = _mm_add_epi16(sum, _mm_cvtepu8_epi16(*(__m128i *) &mem)); 

: 저는 현재 메모리 블록 (가, 256 바이트로 보장 그래서 오버 플로우 걱정을)를 합산이 같은 코드를 남은 바이트, 내가 사용할 수 있습니다

__mm128i sum = _mm_add_epi16(sum, 
          _mm_mask_cvtepu8_epi16(_mm_set1_epi16(0), 
                (__mmask8)_mm_set_epi16(0,0,0,0,1,1,1,1), 
                *(__m128i *) &mem)); 

그러나, _mm_mask_cvtepu8_epi16이다 (참고 ... __mmask8의 종류는 내가 찾을 수 있습니다 어디서나 문서화하지 않는 것, 그래서 나는 추측하고있다) AVX-512 지시 사항, 그래서 거기에 duplic하는 방법입니다 먹은거야? 나는 시도 : 그냥 직접 for (int i = 0; i < remaining_bytes; i++) sum += mem[i]; 더 나은 성능을 준 있도록

mm_mullo_epi16(_mm_set_epi16(0,0,0,0,1,1,1,1), 
       _mm_cvtepu8_epi16(*(__m128i *) &mem)); 

그러나 캐시 매점이 있었다. 귀하의 예제 문제를 들어

+0

당신이 뭘하고 있는지 분명하지 않습니다. AVX512 하드웨어를 가지고 있지만 지원할 컴파일러가 없습니까? 128b (예 :'_mm_mask_cvtepu8_epi16') 및 256b 마스크 작업에는 KNL에없는'AVX-512VL '이 필요하지 않습니다. SSE 전용 솔루션이 필요하십니까? –

+0

for (int i = 0; i

+0

@ Zboson, 예,이 시점에서 컴파일러를 쉽게 업그레이드 할 수 없습니다.특히 간단한 for 루프에 대해서는 아무런 문제가 없습니다 만 실제 루프 몸체는 단지 합계보다 조금 복잡하기 때문에 더 좋은 방법이 있는지 궁금해했습니다. 저는 원이 있고 그 사이의 상대적인 무게를 계산하고 있습니다. (왼쪽 및 오른쪽) 및 (위 및 아래) 반쪽. –

답변

2

나는이 질문을 우연히 발견하는 일이,이 여전히 문제의 경우는 여전히 대답을 못했듯이 ...

는 올바른 방향으로 가고있는 것입니다.

  • 곱하기는 상대적으로 느린 작업이므로 _mm_mullo_epi16의 사용을 피해야합니다. 비트 AND는 훨씬 더 빠른 연산이므로 예를 들어 _mm_and_si128을 사용하십시오. _mm_and_si128(_mm_cvtepu8_epi16(*(__m128i *) &mem), _mm_set_epi32(0, 0, -1, -1))
  • 캐시 스톨이 무슨 뜻인지 잘 모르겠지만 메모리 액세스가 병목 현상이고 컴파일러가 레지스터에 위의 상수를 입력하지 않으면 _mm_srli_si128(vector, 8)과 같은 것을 사용할 수 있습니다. 추가 레지스터/메모리로드가 필요하지 않습니다. 교대는 AND보다 느릴 수 있습니다. 항상 8 바이트의 경우
  • , 당신은 나머지 수는 요소의 고정 된 수의 (예를 들어 당신이 어떤 임의의 n에 대한 n%16 바이트이)가 아닌 경우 _mm_move_epi64
  • 이 중에 사건을 해결하지 사용할 수 있습니다. AVX-512는 실제로이 문제를 해결하지 못합니다.이 케이스를 처리해야하는 경우 남은 항목에 따라 마스크 및 AND 테이블을 만들 수 있습니다 (예 : _mm_and_si128(vector, masks[n & 0xf])
  • (_mm_mask_cvtepu8_epi16은 그래서 당신의 예를 다소 혼란, 벡터의 낮은 반에 대한 관심 - 그 이후 요소가 완전히 anway을 무시하고 있기 때문에, 당신은 아무것도 마스크 할 필요가 없습니다 것입니다)

에 보다 일반적인 수준 인 마스크 작업은 실제로는 _mm_blend_epi16 (또는 이와 동등한 작업) 임베드 된 것입니다. 관용구를 초기화하기 위해 위의 그림과 같이 쉽게 _mm_and_si128/_mm_andnot_si128을 에뮬레이션 할 수 있습니다.

+1

AVX512는이를 해결합니다. 정수 쉬프트와'kmov '로 컴파일 할'__mask32 = (uint32_t) -1UL >> ((32-bytes_left) & 31')을 할 수 있습니다. 물론 다양한 기술을 사용하여 AVX2에서도 마스크를 생성 할 수 있습니다 . https://stackoverflow.com/questions/34306933/vectorizing-with-unaligned-buffers-using-vmaskmovps-generating-a-mask-from-am –

+0

좋은 지적, 그것에 대해 생각하지 않았다. 고마워요. ! – zinga