2012-04-09 5 views
4

128 비트 변수/레지스터에 16 개의 아스키 문자 (따라서 16 개의 8 비트 숫자)가 있다고 가정합니다. 그 비트가 높을 비트 마스크 (비트 위치 (인덱스)가 16 문자로 표시됨)를 만들고 싶습니다.SSE/SSE2/SSE3/SSE4 명령어를 사용하여 여러 개의 숫자에서 비트 마스크를 효율적으로 생성하는 방법

예를 들어, 16 자로 구성된 문자열이 "CAD..."이면 비트 마스크 67 번째 비트에서 65 번째 비트, 68 번째 비트 등은 1이어야합니다. 나머지 비트는 0이어야합니다. SIMD 명령어를 사용하여 특별히 할 수있는 방법은 무엇입니까?

기술 중 하나가 다음과 같이 추가 된 것을 알고 있습니다. 2^(67-1)+2^(65-1)+2^(68-1)+... 그러나 많은 수의 작업이 필요합니다. 가능하다면 1/2 작업/지침으로 수행하고 싶습니다.

해결 방법을 알려주세요.

+2

글자를 테스트했거나 누락 된 것처럼 들릴까요? – Mysticial

+1

AVX2도 수집/분산이 효율적으로 할 수 있다고 생각하지 않습니다 ... – Mysticial

+0

@ 신비로운, 코멘트 주셔서 감사. 예, 당신의 권리, 나는 발생했거나 누락 된 문자를 테스트하려고합니다. 무차별 대입 (2의 거듭 제곱) 방법보다 다른 방법을 더 잘 상상할 수 있습니까? –

답변

4

SSE4.2에는 원하는 피연산자를 수행하는 하나의 명령이 있습니다. 즉각 피연산자 0이있는 PCMPISTRM 피연산자 중 하나에 ASCII 문자가 있어야합니다. 32-33, ... 47 같은 값을 갖는 상수 벡터 XMM0의 최하위 16 비트에서 결과를 얻습니다. 128 비트가 필요하기 때문에이 명령어는 다른 상수 벡터 (인쇄 가능한 ASCII 문자 만 필요하면 6 번)로 8 번 실행해야합니다. 각 PCMPISTRM 다음에 비트 OR을 사용하여 결과를 일부 XMM 레지스터에 누적하십시오.

이 방법에는 두 가지 단점이 있습니다. (1) PCMPISTRM의 세부 사항을 이해하려면 인텔 아키텍처 소프트웨어 개발자 설명서를 읽어야합니다. (아마도 이것이 가장 복잡한 SSE 명령 일 것입니다.) (2)이 명령은 상당히 느립니다 네 할렘에서 1/2, 샌디 브릿지에서 1/3, 불도저에서 1/4). 따라서 '무차별 대항'방식보다 속도가 훨씬 향상됩니다.

+0

감사합니다. Evgeny Kluev. 나는 이것이 매우 효율적이지 않은 방법이라는 것을 이해합니다. 그러나 아마도 지금은 더 좋은 길은 없을 것입니다. –