2012-02-23 55 views
3

我已經將一部分算法從C轉換爲ARM彙編(使用NEON指令), ,但現在它比原始C代碼慢2倍。 如何提高性能?ARM彙編NEON - 提高性能

目標是ARM Cortex-A9。

算法從數組中讀取64位值。從這個值中提取一個字節,然後將其用作另一個表的查找值。 這部分完成了大約10次,並且每個結果表值與其他值進行異或,並將最終結果寫入另一個數組。

像這樣:

result[i] = T0[ GetByte0(a[i1]) ]^T1[ GetByte1(a[i2]) ]^...^T10[ (...) ]; 

在我的方法我加載「一」在NEON寄存器,然後移動在一個臂寄存器中的右字節整個陣列,計算偏移量,然後加載從該值表:

vldm.64 r0, {d0-d7}   //Load 8x64Bit from the input array 

vmov.u8 r12, d0[0]   //Mov the first Byte from d0 into r12 
add r12, r2, r12, asl #3 // r12 = base_adress + r12 << 3 
vldr.64 d8, [r12]   // d8 = mem[r12] 
. 
. 
. 
veor d8, d8, d9    // d8 = d8^d9 
veor d8, d8, d10   // d8 = d8 ^d10  ...ect. 

其中r2保存查找表的基址。

adress = Table_adress + (8* value_fromByte); 

此步驟(開始時加載除外)完成100次。爲什麼這麼慢?

還什麼都之間「VLD」 的差異「VLDR」「VLDM」 - ,哪一個是最快的。 我怎樣才能執行偏移量計算只在霓虹燈註冊? 謝謝。

+0

我不認爲你的C代碼匹配的描述。 C是異或同一個字的多個字節,但quesiton說每個字節用於索引下一個字節。如果無法清晰顯示,我們無法優化代碼。 – phkahler 2012-02-23 14:51:32

+0

是的你是對的。我編輯它。它總是另一個詞。 – HectorLector 2012-02-23 14:55:43

回答

1

可能是你可以嘗試

ldrb  r12, [r0], #1 
add  r3, r2, r12, asl #3 
vld1.64 {d0}, [r3] 

ldrb  r12, [r0], #1 
add  r3, r2, r12, asl #3 
vld1.64 {d1}, [r3] 
veor  d0, d0, d1   // d8 = d8^d1 

ldrb  r12, [r0], #1 
add  r3, r2, r12, asl #3 
vld1.64 {d1}, [r3] 
veor  d0, d0, d1   // d8 = d8^d1 

... 

這不會是最好的解決辦法。之後,您可以通過重新訂購說明來提高性能。

+0

是的重新排序是最後一部分。我現在用ldrb指令來嘗試它,但它似乎無法從.quad值加載一個字節。我定義我的查找表彙編這樣的: 。全球T0 T0: .quad 0xc6a597f4a5f432c6 .quad 0xf884eb9784976ff8 但LDRB R1,T0失敗。 爲什麼我應該使用「vld1.64」而不是「vldr.64」? – HectorLector 2012-02-23 15:43:20

+1

這可能是進行實際查找的唯一方法,因爲查找值是64位的。通過在四寄存器上執行操作,可以減少veor操作的數量。將四個查找值加載到d0,d1,d2和d3中。先做好q0,q0,q1,然後再做d0,d0,d1,你將在兩次操作中完成四個值的異或運算。 – Leo 2012-02-23 21:07:16

+0

使用ldrb它現在比C-Version更快一點。您是否有任何關於重新排序代碼以提高性能和/或AR/NEON流水線的技巧? – HectorLector 2012-02-29 12:20:23

2

不使用

vmov.u8 r12, d0[0] 

從NEON寄存器中移動數據到ARM寄存器是你能做的最糟糕的事情。

也許你應該看VTBL指令! 你是什麼字節範圍0..255?

+0

謝謝你的迴應,我會盡力改變這種情況。我試圖實現的是這樣的:我有一個2維數組(8x8字節)。我需要每一列有一個不同的字節。該字節值是另一個aray(64位)的索引。所以我需要得到正確的字節值,在表中查找我的值,然後異或所有找到的值。我希望這或多或少是可以理解的。 – HectorLector 2012-02-23 14:50:18

2

Neon不能處理大於VTBL指令限制的查找(如果我沒有記錯,則爲32字節)。
如何創建查找表開始?如果只是計算,只要讓氖做算術而不是求助。 這樣會更快。

+0

查找表是靜態和硬編碼的。約2000個64位值。 – HectorLector 2012-02-25 22:08:03

0

用NEON「intrinsics」嘗試一下。基本上它們是C函數,可以編譯成NEON指令。編譯器仍然可以執行所有指令調度,並且免費獲得其他無聊的東西(移動數據)。

它並不總是完美的工作,但它可能比試圖手動編碼更好。

尋找arm_neon.h

+1

謝謝。我嘗試過,但速度不夠快。 – HectorLector 2012-02-25 22:07:03