2016-09-09 40 views
0

我有4個車道D0,D1,D2,D3,我想平均四個相鄰:ARM霓虹燈:添加兩次相鄰平均四個相鄰像素

d0[0] = (d0[0] + d0[1] + d0[2] + d0[3])/4 
d0[1] = (d0[4] + d0[5] + d0[6] + d0[7])/4 
d0[2] = (d1[0] + d1[1] + d1[2] + d1[3])/4 
... 

是以下霓虹燈代碼是否正確?

vpaddl.u8 d0, d0 
vpaddl.u8 d1, d1 

vpaddl.u8 d2, d2 
vpaddl.u8 d3, d3 

vpadd.u16 d0, d0, d2 
vshrn.u16 d0, q0, #2 

如果是的話,有沒有更快的方法來做到這一點?

EDIT 1

上述代碼是不正確的。我想出了以下幾點:

vpaddl.u8 d0, d0 
vpaddl.u8 d1, d1 
vpaddl.u8 d2, d2 
vpaddl.u8 d3, d3 
vuzp.u16 q0, q1 
vadd.u16 q0, q0, q1 
vshrn.u16 d0, q0, #2 

這是工作。這與'Notlikethat'接受的答案的第二個建議非常相似,但是採用了不太優化的方式。

+1

您對此數據事先做了哪些其他操作?一般來說,儘可能避免水平操作,因此首先將數據排列成不同的位置將是_best_選項 - 如果能夠將d0-d3中的相鄰數據與「vld4」交錯,則可以輕鬆地使用正常的並行操作。 – Notlikethat

+0

我同意但不幸的是,不,我不能在這種情況下做一個vld4。我也在考慮使用zip或者vext來重新排列數據,但我不確定我會減少指令的數量,而且我可用通道的數量有限。請注意,我的問題仍然存在(!),代碼是否至少正確? – gregoiregentil

回答

3

經過一段時間playing around後,我會說在給定的約束條件下,您的一般方法可能與您將要獲得的一樣好。有了超過4個寄存器值的數據一次性工作,和/或有機會吸收算法中其他地方重新組合矢量的成本,結論可能會有所不同,但否則可行的選擇是非常有限的。

你,但是,你的第二輪削減,並在第一輪忘記d1d3可以因爲不像vpadd簡化到兩個指令,vpaddl確實有一個Q-登記表格。固定這些目的了這樣的:

vpaddl.u8 q0, q0 
vpaddl.u8 q1, q1 
vpadd.u16 d0, d0, d1 
vpadd.u16 d1, d2, d3 
vshrn.u16 d0, q0, #2 

在純粹的指令數計算,則可能通過執行部分轉然後直接累加2個成對減少去低,從而:

vuzp.16 q0, q1 
vpaddl.u8 q0, q0 
vpadal.u8 q0, q1 
vshrn.u16 d0, q0, #2 

但Q型vuzp真的昂貴的一切,我可以找到指令時機,並積累vpadal也不是免費的,所以這幾乎肯定會最終表現惡化整體比莫重新簡單的版本。

+0

加一個「玩」的鏈接。這是一個非常酷的在線工具! – gregoiregentil