Non posso garantire più veloce, ma questo è un approccio che utilizza SSE. Otto conversioni da 12-16 bit sono fatte per iterazione e due conversioni (circa) sono fatte per step (cioè, ogni iterazione richiede più passaggi).
Questo approccio è a cavallo degli interi a 12 bit attorno ai limiti di 16 bit nel registro xmm. Qui sotto mostra come è fatto.
- È in uso un registro xmm (assumere xmm0). Lo stato del registro è rappresentato da una riga di lettere.
- Ogni lettera rappresenta 4 bit di un intero 12 bit (ovvero, AAA è l'intera prima parola a 12 bit nell'array).
- Ogni spazio rappresenta un limite di 16 bit.
- >> 2 indica uno spostamento logico di destra di un byte.
- Il simbolo carota (^) viene utilizzato per evidenziare quali rilevanti numeri interi a 12 bit si trovano a cavallo di un limite di 16 bit in ogni passaggio.
:
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
^^^
Ad ogni passo, siamo in grado di estrarre i numeri interi 12bit allineati e memorizzarli nel registro delle XMM1. Alla fine, il nostro xmm1 avrà il seguente aspetto. I punti interrogativi indicano valori che non ci interessano.
AAA? ?BBB CCC? ?DDD EEE? ?FFF GGG? ?HHH
Estrarre alto allineato interi (A, C, E, G) in XMM2 e poi, sul XMM2, eseguire uno shift verso destra parola logica di 4 bit. Ciò convertirà gli interi allineati in alto in allineati bassi. Miscelare questi numeri interi modificati in xmm1. Lo stato di XMM1 è ora:
?AAA ?BBB ?CCC ?DDD ?EEE ?FFF ?GGG ?HHH
finalmente possiamo mascherare i numeri interi (ad esempio, convertire il s 'a 0 di?) Con 0FFFH su ogni parola.
0AAA 0BBB 0CCC 0DDD 0EEE 0FFF 0GGG 0HHH
Ora xmm1 contiene otto numeri interi convertiti consecutivi.
Il seguente programma NASM dimostra questo algoritmo.
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
Ho aggiunto del codice. Converti un'immagine a 12 bit in una matrice mobile, ma può anche essere convertita in un UInt16 (cambia semplicemente il cast) – Gilad
Questa è una domanda divertente e interessante. Di certo non ha bisogno di essere chiuso. – erisco
Il più veloce ... dipende dalla piattaforma. RAM, cache, ecc. Ecc. Non è possibile utilizzare SSE solo con il linguaggio C#. Definire i parametri/vincoli e attenersi a loro, per favore. Altrimenti la domanda in realtà non è rispondente –