2011-10-17 35 views
2

我剛開始嘗試使用NEON優化一些android代碼。但是,我遇到了一些問題。主要問題是我真的無法弄清楚如何做一個快速的16位浮點轉換。使用ARM霓虹燈將短陣列轉換爲浮點

我看到它可能使用vcvt.s32.f32將多個32位整數轉換爲1個SIMD指令的浮點數。但是,如何將一組4個S16轉換爲4個S32?我認爲它與VUZP指令有關,但我不知道如何...

同樣,我看到它可能使用VCVT.s16.f32一次轉換1 16位浮點數,但可能雖然這很有幫助,但使用SIMD不能完成它似乎非常浪費。

多年來,我在許多不同的平臺上編寫過彙編程序,但由於某些原因,我發現ARM文檔完全不可理解。

因爲這樣的任何幫助將HUGELY讚賞。

還有什麼辦法可以獲得NEON設備的吞吐量和延遲數據嗎?

在此先感謝!

+1

對NEON並不熟悉,但不能將4個短褲「拓寬」爲4個整數然後轉換?看看[GCCs內在函數](http://gcc.gnu.org/onlinedocs/gcc/ARM-NEON-Intrinsics.html)我想也許vaddl.s16的零秒操作數可以。 – user786653

+0

@ user786653:嗯,它可能只是做到了這一點:D – Goz

+0

是的..這似乎工作。不能相信我沒有注意到這個說明.. – Goz

回答

4

如果沒有其他的計算要與16位整數轉換爲32位整數,你可以去一起做uint32x4_t = vmovl_u16(uint16x4_t)

如果正在前進行的任何簡單的加法或乘法等轉換,你可以結合他們在一個單一的指令,如int32x4_t = vmull_u16(int16x4_t,int16x4_t)int32x4_t = vaddl_u16(int16x4_t,int16x4_t) etc等,從而節省一些數量的週期。

2

在我的評論中詳細地闡述了一點:您希望在轉換爲4個32位浮點數之前將4個16位寄存器「擴大」爲4個32位整數。看看指令集我不認爲有更快的轉換路徑,但我可能很容易出錯。

直接的方法是使用vaddl.s16第二個操作數爲四個零,但除非您只進行轉換,否則您通常可以將轉換與前一個操作結合使用。例如。如果您將兩個int16x4寄存器相乘,則可以使用vmull.s16直接獲取32位輸出,而不是稍後先乘以和加寬(假設您不依賴於任何截斷行爲)。

1

爲什麼使用vaddl浪費週期初始化一個有價值的寄存器0?

vmovl.s16 Q0,D1

然後轉換Q0

,會做。

我的問題是:

  • 是絕對有必要將它們轉換爲浮動? NEON比浮點運算要快得多。 (執行和管道)因此,在大多數情況下,定點操作將更加合適,這要歸功於強大的長,寬,窄模型以及算術指令和自動輪/飽和度選項。

PS:奇怪,我認爲ARM的PDF是最好的。