2016-07-14 2 views
0

일부 코드를 포팅하는 중입니다. SSE4 내장 함수를 많이 사용합니다. SSE가 아닌 구현이 있지만 SSE2 만있는 CPU가 더 빠른 기능을 계속 사용할 수 있기를 바랍니다._mm_insert_epi32에 해당하는 SSE2가 있습니까?

foo = _mm_insert_epi32(vec, 0, 0); 
: -

누군가가 _mm_insert_epi32위한 효율적인 교체를 제안 할 수 생각, 나는 모든 다른 사실, 두 번째와 함수의 세 번째 인수는 내 경우에는 제로입니다 ... 이미 덮여있어

답변

2

사실 벡터의 낮은 요소를 0으로 만들고 싶습니까? _mm_insert_epi32의 사용 사례는 좋지 않습니다. Intel CPU에서는 2 μops이고, 그 중 하나는 셔플 포트가 필요합니다. 모두 당신의 SSE4.1 및 SSE2 버전에서

, 또는

foo = _mm_and_si128(vec, _mm_set_epi32(-1,-1,-1, 0)); // mask off the low element 

사용 제로화 벡터에서 movss를 사용하지만,이 두 개의 정수 지침 사이의 FP shuffle을 사용하는 바이 패스 지연이 발생할 수 있습니다 . C intrinsics 버전에는 성가신 양의 캐스팅이 있으므로 asm으로 읽기가 쉽습니다.

# vec in xmm0 
pxor xmm1, xmm1 ; _mm_setzero_si128() 
movss xmm0, xmm1 ; zero the low 32 bits of xmm0 

_mm_insert_epi16

는 변수 내용으로 낮은 요소 이외의 요소를 대체 할 싶어도, 거의 확실하게이 작업을 수행하는 가장 좋은 방법은 아닙니다. 2-uop 명령이지만, 많은 경우 4 uop 미만으로 작업을 완료 할 수 있습니다.

가변 내용의 경우 _mm_cvtsi32_si128 (movd)을 사용하고 두 벡터를 함께 섞는 것이 좋습니다. 언팩 지시문은 두 개의 레지스터에서 데이터를 결합하는 데 편리합니다. 따라서 shufps도 있습니다 (예, 정수 데이터에 사용할 수 있음).

vec을 교체하여 교체 할 요소가 낮은 요소이므로 movss (또는 AND/OR)으로 바꿀 수 있습니다.

아마도 2x pinsrw은 일반적인 경우에는 끔찍하지 않지만 가장 구체적인 경우는 더 나은 것을 제안해야합니다. 효율적인 코드를 작성하는 데 도움이되는 추가 자료는 http://agner.org/optimize/ 태그 위키를 참조하십시오.

관련 문제