2013-05-31 22 views
0

我想弄清楚是否以及如何將特定的現有代碼並行化以用於ARM Cortex-A9 NEON SIMD單元。這是代碼:可能爲ARM NEON並行化濾波器?

for(int i=0; i < 11; i++) 
{ 
    f4UF1 *= F[i]; 

    A[i][2] = A[i][1]; 
    A[i][1] = A[i][0]; 
    A[i][0] = f4UF1; 

    B[i][2] = B[i][1]; 
    B[i][1] = B[i][0]; 

    C[i] = 0; 

    C[i] += D[i][0] * A[i][0]; 
    C[i] += D[i][1] * A[i][1]; 
    C[i] += D[i][2] * A[i][2]; 

    C[i] -= E[i][1] * B[i][1]; 
    C[i] -= E[i][2] * B[i][2]; 

    B[i][0] = C[i]/E[i][0]; 

    f4UF1 = B[i][0]; 
} 

我已經看過的代碼相當多的現在,我幾乎可以肯定,它不能有效地並行處理,但我想,我可以試試看問這裏。我不期待現成的代碼,只是想法如何做到這一點。謝謝:)

+0

什麼是數據類型?你應該粘貼一些能夠滿足編譯器的東西。 – auselen

+0

編譯它並檢查輸出可能會提供一些見解。 – marko

+0

可以使用vext指令向下滑動元素。你也可以做乘法/加法。如果你在NEON中編寫它,看起來你可以改進幾個週期。唯一的問題是需要變成乘數的鴻溝。 – BitBank

回答

1

所以是的,這看起來像一個biquad,其係數每個樣本都會改變,也許是因爲您正在平滑它們。

作爲一位評論者提到,您可能需要預先計算1/E[i][0]縮放因子,並將其轉換爲其他係數以減少乘法的次數,特別是在浮點平臺上。您也可以經常對biquad進行標準化以擺脫D[i][0](使其成爲1.0),並且僅對整個輸出應用標量。

當然,你可能已經意識到,要保持在循環過程中的寄存器一切,然後循環完成後,他們只寫出來的內存... ;-)

之後,有是我知道的兩種矢量化技術(儘管我對Nils的想法也很感興趣):

  1. 通道矢量化 - 最簡單。如果您需要一次對多個數據集應用濾波器(例如,非常適用於立體聲音頻),您可以同時使用兩組音頻數據來操作兩組係數。我發現如果您使用所有SP浮點,氖提供兩個通道的正確數量的寄存器。即時2x加速確實。
  2. 循環展開。在這裏詳細描述這有點棘手,但幸運的是這裏有一個不錯的頁面:http://reanimator-web.appspot.com/articles/simdiir。這種技術增加了極點/零點對,以便一次計算更多的樣品。然而,額外的極點當然會給濾波器的穩定性增加額外的條件,所以你必須小心。在你的情況下,當係數似乎是動態的,這可能是一種噩夢來確保。