2012-02-16 199 views
2

我是新來的彙編和NEON編程。 我的任務是部分由C轉換算法的使用NEON指令ARM彙編。 該算法需要一個INT32陣列,從這個數組加載不同的值,做了一些bitshifting和XOR,並且在另一個數組寫入的結果。 後來,我將使用帶有64位值的數組,但現在我只是嘗試重寫代碼。ARM NEON彙編 - 使用和理解

C Pseudo code: 

out_array[index] = shiftSome(in_array[index])^shiftSome(in_array[index]); 

因此,這裏有我的關於NEON指令的問題:

1)如果我打開一個寄存器:

vld1.32 d0, [r1] 

將其從內存或2x32Bit只加載32位填寫64Bit霓虹燈D-Register?

2)我怎樣才能訪問2/4/8(I32,I16,I8)的d-註冊的部分?

3.)我試圖從偏移量的數組中加載不同的值,但它不似乎 工作...我在做什麼錯...這裏是我的代碼: (這是一個整數數組所以我正嘗試加載例如3-元件,其應具有64位= 8字節的偏移)

asm volatile(
"vld1.32 d0, [%0], #8 \n"  
"vst1.32 d0, [%1]" : : "r" (a), "r" (out): "d0", "r5"); 

其中「a」是數組和「out」是一個指針,指向一個整數(用於調試)。

4)我加載從數組我需要把它轉移到右邊的值之後,但它似乎並沒有工作:

vshr.u32 d0, d0, #24  // C code: x >> 24; 

5)是否有可能只裝1字節在霓虹燈註冊表中,這樣我就不必移動/掩蓋某些東西來獲取我需要的一個字節?

6)我需要使用內聯彙編程序,但我不知道最後一行是什麼:

input list : output list : what is this for? 

7)你知道與代碼示例什麼好NEON參考?

規劃署上的三星Galaxy S2,Cortex-A9處理器運行,如果有什麼差別。謝謝您的幫助。

----------------編輯-------------------

這就是我發現:

  1. 它總是加載完整寄存器(64位)
  2. 您可以使用「VMOV」指令傳遞一個霓虹燈的一部分註冊一個ARM寄存器。
  3. 該偏移量應該在一個arm寄存器中,並且將在之後的 的基地址上加上內存訪問。
  4. 這是「慘敗REG名單」。使用的每一種和 既不在輸入或輸出列表註冊,應該寫在這裏。
+0

2.從SIMD移動內容寄存器ARM寄存器會造成一個完整的管道沖洗,你花費大約14個週期。躲開它。 – 2017-10-15 06:42:07

回答

10

我可以回答你的大部分問題:(更新:澄清「裏」的問題)

1)NEON指令只能加載並同時儲存整個寄存器(64位,128位)往返記憶。有一個MOV指令變體,允許將單個「通道」移入或移出ARM寄存器。

2)您可以使用NEON MOV指令來影響單通道。執行太多單一元素操作時性能會受損。 NEON指令通過對矢量(浮點/整數組)執行並行操作來使應用程序性能受益。

3)ARM彙編語言中的立即數偏移是字節,而不是元素/寄存器。 NEON指令允許使用寄存器遞增遞增,而不是立即數。對於正常的ARM指令,後增加8會將8個字節添加到源指針。

4)NEON中的位移影響矢量的所有元素。使用vshr.u32向右移位24位會將32位無符號長整數移位24位,並丟棄移出的位。 5)NEON指令允許將單個元素移入或移出正常的ARM寄存器,但不允許從內存直接加載或存儲到「通道」中。

6)?

7)從這裏開始:http://blogs.arm.com/software-enablement/161-coding-for-neon-part-1-load-and-stores/ ARM網站上有關於NEON的很好的教程。

+2

關於1和5:可以在NEON寄存器中加載和存儲單個元素。只需在NEON寄存器之後用[]指定元素索引即可。相同的符號可用於例如將矢量與另一矢量中的單個元素相乘。 – Leo 2012-02-21 11:26:20

+2

非常正確,除了後增量。 NEON不能添加立即值作爲後增量。您可以使用寄存器ARM寄存器來做到這一點或使用!這將增加數據的大小。 – webshaker 2012-02-21 14:43:14

0

6)Clobbered寄存器。

asm(code : output operand list : input operand list : clobber list); 

如果您正在使用的寄存器,沒有被作爲操作數過去了,你需要通知 這個編譯器。以下代碼將將值調整爲四的倍數。它 使用r3作爲臨時寄存器,並通過在 clobber列表中指定r3來讓編譯器知道這一點。此外,CPU狀態標誌由ands指令修改。 將僞寄存器cc添加到clobber列表將使編譯器也通知 此修改。

asm (
"ands R3, %1, #3" 
"eor %0, %0, r3" 
: "=r"(len) 
: "0"(len) 
: "cc", "r3" 
);