Ben en hızlı garanti edemez, ancak bu SSE kullanan bir yaklaşımdır:
Kod ekledi. Yineleme başına sekiz adet 12-16 bit dönüşüm yapılır ve adım başına iki dönüşüm (yaklaşık) yapılır (yani, her bir yinelemede birden çok adım atılır).
Bu yaklaşım, xmm kaydındaki 16 bitlik sınırlar etrafındaki 12 bit tamsayıları aşıyor. Aşağıda bunun nasıl yapıldığını gösterir.
- Bir x mm kayıt kullanılıyor (xmm0 varsayalım). Kayıt durumu bir harf satırı ile temsil edilir.
- Her harf 12 bit tamsayıdan 4 bit gösterir (yani, dizideki ilk 12 bitlik kelimenin tamamı AAA'dur).
- Her boşluk 16 bitlik bir sınırı temsil eder.
- >> 2, bir baytın mantıksal olarak doğru kaydırılmasını belirtir.
- Havuç (^) simgesi, her bir adımda, ilgili 12 bit tamsayıların 16bit sınırını geçtiğini vurgulamak için kullanılır.
: Her adımda
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
^^^
, Hizalandığımız 12bit tamsayılar ayıklamak ve XMM1 defterine bunları saklayabilir. Sonunda, bizim xmm1 aşağıdaki gibi görünecek. Soru işaretleri, önemsemediğimiz değerleri belirtmektedir.
AAA? ?BBB CCC? ?DDD EEE? ?FFF GGG? ?HHH
yüksek hizalanmış tamsayılar (A, C, E, G) XMM2 içine ve daha sonra, XMM2 ile, 4 bitlik bir sağ mantıksal kelime kayma gerçekleştirmek ekstrakte edin. Bu, yüksek hizalanmış tam sayıları düşük hizada dönüştürür. Bu ayarlanmış tam sayıları xmm1'e geri karıştırın. XMM1 durumu şimdi:
?AAA ?BBB ?CCC ?DDD ?EEE ?FFF ?GGG ?HHH
Sonunda tamsayılar dışarı maskeleyebilir (yani dönüştürmek 'ın 0 en etmek?) 0FFFh her kelimenin üstünde.
0AAA 0BBB 0CCC 0DDD 0EEE 0FFF 0GGG 0HHH
Artık xmm1, birbirini izleyen sekiz dönüştürülmüş tam sayı içeriyor.
Aşağıdaki NASM programı bu algoritmayı göstermektedir.
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
Bazı kodları ekledim. Bir 12bit resmini bir float dizisine dönüştürün ancak aynı zamanda bir UInt16'ya da (sadece döküm işlemini değiştirerek) çevirebilirsiniz. – Gilad
Bu eğlenceli ve ilginç bir soru. Kesinlikle kapatılmaya gerek yoktur. – erisco
En Hızlı ... platforma bağlıdır. RAM, önbellek vb. .. Sadece C# diliyle SSE kullanamazsınız. Parametrelerinizi/kısıtlamalarınızı tanımlayın ve onlara bağlı kalın, lütfen. Aksi durumda, soru –