nie mogę zagwarantować najszybciej, ale jest to podejście, które wykorzystuje SSE. Osiem konwersji 12-16-bitowych jest wykonywanych w iteracji, a dwie konwersje (w przybliżeniu) są wykonywane na każdy krok (tj. Każda iteracja wymaga wielu kroków).
Podejście to obejmuje 12-bitowe liczby całkowite wokół granic 16-bitowych w rejestrze xmm. Poniżej pokazano, jak to się robi.
- Używany jest jeden rejestr xmm (załóżmy xmm0). Stan rejestru jest reprezentowany przez jedną linię liter.
- Każda litera reprezentuje 4 bity z 12bitowej liczby całkowitej (tj. AAA jest całym pierwszym 12-bitowym słowem w tablicy).
- Każda przerwa reprezentuje 16-bitową granicę.
- >> 2 oznacza logiczne przesunięcie w prawo o jeden bajt.
- Symbol marchewki (^) służy do zaznaczenia, które 12-bitowe liczby 12-bitowe znajdują się na każdym kroku 16-bitowej granicy.
:
load
AAAB BBCC CDDD EEEF FFGG GHHH JJJK KKLL
^^^
>>2
00AA ABBB CCCD DDEE EFFF GGGH HHJJ JKKK
^^^ ^^^
>>2
0000 AAAB BBCC CDDD EEEF FFGG GHHH JJJK
^^^ ^^^
>>2
0000 00AA ABBB CCCD DDEE EFFF GGGH HHJJ
^^^ ^^^
>>2
0000 0000 AAAB BBCC CDDD EEEF FFGG GHHH
^^^
Na każdym kroku możemy wyodrębnić wyrównane całkowitymi 12bit i przechowywać je w rejestrze XMM1. Na końcu nasz xmm1 będzie wyglądał następująco. Znaki zapytania oznaczają wartości, na których nam nie zależy.
AAA? ?BBB CCC? ?DDD EEE? ?FFF GGG? ?HHH
Ekstrakt wysokie wyrównane całkowite (A, C, E, G) do XMM2 a następnie na XMM2 należy przeprowadzić odpowiedni logiczny słowo przesunięcie 4 bitów. Spowoduje to przekonwertowanie liczb całkowitych o wysokiej wartości na wartość wyrównaną do dołu. Połącz te dostosowane liczby całkowite z powrotem do xmm1. Stan XMM1 jest teraz:
?AAA ?BBB ?CCC ?DDD ?EEE ?FFF ?GGG ?HHH
Wreszcie możemy zamaskować się z liczb całkowitych (tzn przekonwertować 's do 0'S?) Z 0FFFh na każdym słowie.
0AAA 0BBB 0CCC 0DDD 0EEE 0FFF 0GGG 0HHH
Teraz xmm1 zawiera osiem kolejnych skonwertowanych liczb całkowitych.
Następujący program NASM demonstruje ten algorytm.
global main
segment .data
sample dw 1234, 5678, 9ABCh, 1234, 5678, 9ABCh, 1234, 5678
low12 times 8 dw 0FFFh
segment .text
main:
movdqa xmm0, [sample]
pblendw xmm1, xmm0, 10000000b
psrldq xmm0, 1
pblendw xmm1, xmm0, 01100000b
psrldq xmm0, 1
pblendw xmm1, xmm0, 00011000b
psrldq xmm0, 1
pblendw xmm1, xmm0, 00000110b
psrldq xmm0, 1
pblendw xmm1, xmm0, 00000001b
pblendw xmm2, xmm1, 10101010b
psrlw xmm2, 4
pblendw xmm1, xmm2, 10101010b
pand xmm1, [low12] ; low12 could be stored in another xmm register
Dodałem kod. Konwertuj obraz 12-bitowy na tablicę zmiennoprzecinkową, ale można go również przesłać do UInt16 (wystarczy zmienić rzutowanie). – Gilad
To zabawne, interesujące pytanie. Z pewnością nie trzeba go zamykać. – erisco
Najszybsza ... zależy od platformy. Pamięć RAM, pamięć podręczna itp. Nie można używać SSE tylko z językiem C#. Zdefiniuj swoje parametry/ograniczenia i trzymaj się ich, proszę. W przeciwnym razie pytanie naprawdę nie jest odpowiedzialne. –