2010-01-13 26 views
1

我正在做一件事情,我希望有輸出選項去視頻覆蓋。有些支持rgb565,如果真的很好,只需複製數據即可。快速rgb565到YUV(或甚至rgb565到Y)

如果不是我必須複製數據與轉換,它是一次幀緩衝區。我會嘗試一些事情,但我認爲這可能是優化者會熱衷於進行一些挑戰的事情之一。

有許多YUV格式,通常支持最簡單的是Y平面,後面是交錯或單獨的UV平面。

使用Linux/xv,但在級別上,我正在處理它只是字節和x86。

我打算專注於質量成本的速度,但有數百種不同的途徑可以嘗試。那裏有一個平衡點。

我看着mmx,但我不確定是否有任何有用的東西。沒有什麼東西讓我覺得特別適合這項任務,並且在寄存器中將事情放到正確的位置需要進行大量的洗牌。

嘗試使用Y = Green * 0.5 + R * 0.25 + Blue *的原始版本不多。 U和V對質量更不重要。你可以在這些頻道上謀殺。

對於一個簡單的循環。

loop: 
movzx eax,[esi] 
add esi,2 
shr eax,3 
shr al,1 
add ah,ah 
add al,ah 
mov [edi],al 
add edi,1 
dec count 
jnz loop 

當然每個指令依賴於一前字的讀取,但不是最好這樣交織男會贏得有點

loop: 
mov eax,[esi] 
add esi,4 
mov ebx,eax 
shr eax,3 
shr ebx,19 
add ah,ah 
add bh,bh 
add al,ah 
add bl,bh 
mov ah,bl 
mov [edi],ax 
add edi,2 
dec count 
jnz loop 

這將是很容易做到與4在時間,也許是爲了一個好處。

任何人都可以拿出更快,更好的東西嗎?

一個有趣的方面是,一個體面的編譯器是否可以產生類似的代碼。

回答

1

你真的想看看,我認爲,這是使用MMX或整數SSE指令。這可以讓你一次處理幾個像素。我想如果你指定了正確的開關,你的編譯器將能夠生成這樣的代碼,特別是如果你的代碼寫的很好。

關於你現有的代碼,我不會打擾交錯不同迭代的指令來獲得性能。所有x86處理器(不包括Atom)和高速緩存的亂序引擎應該處理得很好。

編輯:如果您需要做的水平增加了您可能需要使用PHADDDPHADDW說明。實際上,如果您擁有「英特爾軟件設計手冊」,則應該查看PH*說明。他們可能有你需要的東西。

+0

我看過MMX和SSE。我在總結中提到過。在這種情況下,我看不到任何特別有用的東西,因爲MMX在執行水平操作時受到阻礙。我需要執行的操作是在一個輸入源的不同部分上進行不同級別的乘法(或移位)。 PMADDWD或多或少是我需要執行的操作,但需要將數據轉換爲兩個單詞才能生成雙字結果,然後需要將其提取出來。 我嚴重懷疑亂序的CPU可以顯着加快該循環的短版本。 – Lerc 2010-01-14 06:34:01

+0

我相信PHADDW和類似指令是SSSE3。這削減了太多的系統。包括我的筆記本。所有的好的指示都是遙不可及的。 – Lerc 2010-01-14 07:24:02

1

一個體面的編譯器,考慮到適當的開關來調整最感興趣的CPU變體,幾乎肯定知道更多關於優秀x86指令選擇和調度的知識,而不是任何一個凡人!

看看Intel(R) 64 and IA-32 Architectures Optimization Reference Manual ...

如果您想進入手工優化代碼,一個好的策略可能是讓編譯器爲您生成彙編源代碼作爲起點,然後調整它;在每次更改之前和之後進行配置,以確保您實際上將事情做得更好。

+0

這在編譯器中有很多信念。謹慎對待測試? Y =(RGB565&0x7ff >> 4)+(RGB565&0xf800)>> 11 //晚餐時間,所以可能是錯的:-) ,其在ASM是 SHR EAX,3; shr al,1; 加啊,啊; add al,ah; 除了部分寄存器攤位相當緊湊。我真的很好奇編譯器是否採用相同或更好的方法。 (晚餐後我會回來找出格式) – Lerc 2010-01-14 06:47:39

+0

太慢了。編輯按鈕不見了。讓我們嘗試格式化 爲了可讀性,上面的代碼是。 '0x7ff >> 4)+(RGB565&0xf800)>> 11' 和(希望同樣的事情ASM) 'SHR EAX,3; shr al,1;加啊,啊;加人啊,' 。 那現在不是很好: - / – Lerc 2010-01-14 07:28:20