2016-08-09 1 views
0

문제

지시가 주름/A int 내로 int[32] 저장 그것의 첫 번째 비트를 추출하는 것이 존재 하는가?는 정수 배열에서 첫 번째 비트를 추출/수집

  • 본래의 pext에 대해 알고 있지만 그것은 내가 원하는 것만은 아닙니다.

  • 나는 코드가 있지만 어쩌면 거기에 지정된 명령이 있다고 생각합니다.

  • ints 배열은 첫 번째 비트 외에도 0입니다. 에르고, 가면이 필요하지 않아.

코드

void ints2bits(int &bits, int *ints) { 
    bits = (ints[0] << 0) + (ints[1] << 1) + ... + (ints[31] << 31); 
} 

UPDATE & 피드백 :

그냥 테스트 해롤드 제안. 그것은 아주 잘 작동하고 좋은 속도를 얻을 수 있습니다.

+0

배열의 31 개 정수 중 첫 번째 비트를 추출하여 int의 적절한 위치에 비트를 저장하려면 코드가 잘못되었습니다. – sameerkn

+0

잘못이 아닙니다. 나는 그것을 문자 그대로 사용한다. 문제는이 작업에 대한 구체적인 지침이있는 경우에만 해당됩니다. 도중에 배열의 마스킹이 필요하지 않을 수 있습니다. 이는 아마도 그 결함을 주장하는 이유 일 수 있습니다. –

+0

코드에서는 int의 다른 모든 비트가 0이라고 가정하므로 문제 사양에 명시 적으로 명시해야합니다. – samgak

답변

2

많은 데이터를 읽을 수있는 단일 명령은 없지만을 사용하여 4 개 그룹 (AVX2는 8 개)을 빠르게 처리 할 수 ​​있습니다. 부동 소수점 명령어라고 주장한다는 사실을 무시하고, 그냥 4 개의 최상위 비트를 모으고 추가합니다.

_mm_slli_epi32으로 하단 비트를 맨 위로 이동하는 것은 물론 쉽습니다.

그래서

int res = 0; 
for (int i = 0; i < 32; i += 4) { 
    __m128i x = _mm_load_si128((__m128i*)&ints[i]); // I assume it's aligned 
    x = _mm_slli_epi32(x, 31); 
    int bits = _mm_movemask_ps(_mm_castsi128_ps(x)); 
    res += bits << i; 
} 

AVX2에 대한 확장은 매우 분명하다 (테스트하지) 함께 퍼팅.

다른 가능한 방법은 각 차선을 다양한 양 (이전 AVX2 곱하기가 필요함)으로 이동 한 다음 마지막으로 수평 합계를 저장하는 첫 번째 수직적 합계를 합산하는 것입니다. 이것은 아마도 더 느리고 분명히 더 어색 할 것입니다.

관련 문제