簡體   English   中英

在kiss_fft中,為什么kf_bfly2以數組為參數? 參數似乎是一個標量

[英]In kiss_fft, why does kf_bfly2 take an array as argument? The argument seems to be a scalar

Kiss_fft是一個非常簡單的 FFT 實現; 這幾乎是教科書了。 它通過分解 FFT 大小將較大的 DFT 分解為重復的較小的 FFT。 它針對基數 2、3、4 和 5 優化了蝶形函數。

2,3 和 5 蝴蝶是小素數,在因式分解時很常見,但基數 4 蝴蝶是優化的情況,與使用基數 2 兩次*相比,可以節省一些乘法運算*。 例如,對於一個32點FFT,尺寸32被分解成4x4x2 -的兩個階段kf_bfly4接着之一kf_bfly2

但是,這意味着您只能擁有一個kf_bfly2階段。 如果您的 FFT 大小是 4 的倍數,則不會有兩個kf_bfly2 stage2,而是一個kf_bfly4 stage。 這也意味着kf_bfly2函數適用於長度為 1 的“數組”。

在代碼中,聲明是

static void kf_bfly2(kiss_fft_cpx * Fout, const size_t fstride, const kiss_fft_cfg st, int m)

其中Fout是大小為m的“數組”,即始終為 1。蝴蝶循環在Fout ,編譯器當然無法進行數值分析以顯示m==1 但是,由於這是最后的蝴蝶,它經常被調用。

Q1)我的分析是否正確? kf_bfly2確實只用m==1調用嗎?

Q2)假設這確實是一個錯過的優化,有兩種可能的方法。 我們可以從kf_bfly2刪除m參數,或者我們可以將因子分析更改為因子 32 作為 2x4x4(將kf_bfly2提前移動,在大小為 4x4=16 的數組的頂層調用一次)。 什么是最好的?

[*] 基數 4 的蝶形最終具有因子 +1、-1、+i 和 -i,它們可以作為加法和減法來實現。 請參閱為什么kiss_fft 的正向和反向radix-4 計算不同?

要理解“m”的值,它有助於理解 Kiss FFT 的工作原理:它通過分解 FFT 大小將大 FFT 遞歸地轉換為較小的 FFT。 並且有多種可能的因式分解:32 是 4x4x2,但也是 2x4x4。

現在kf_bfly2和其他蝶形函數中的m參數是kf_bfly2所有因子的乘積。 因此,再次以 32 為例, kf_bfly4將在 m=8 和 m=2 時被調用。

我認為kf_bfly2中的m=1因為在我的測試中它總是碰巧是最后一個因素,如果它是一個因素。 如果您使用 221 點 FFT,則最后一個因子將是 17,而不是 2。

但是 34 被分解為 2x17,在這種情況下m==17 這沒有什么特別的原因,這只是kf_factor實現的kf_factor 它通過檢查n%4, n%2, n%3, n%5, n%7, n%9, n%11 ...測試分解。 當然,這不是最有效的方法。 Checking n%9毫無意義,因為您之前已經發現了兩個 3 的因數。

但是請注意,從n%4的位置可以自由檢查因素。 我們可以簡單地最后檢查n%2 如果我們這樣做,那么 34 將被17x217x2而不是2x17 這似乎是一個微不足道的優化,但它確實允許我們刪除kf_bfly2中的循環。 此外,它現在只使用第一個旋轉因子 - 這是一個非常方便的{1 + 0i} 所以kf_bfly2唯一的乘法也被消除了。

優化並不止於此 - 因為kf_bfly2現在小了很多,而且只有一個調用站點*,您的編譯器可能kf_bfly2 kf_work內聯到kf_work 我們從改變的因式分解中知道2只能是最后一個因數,因此我們也可以停止kf_work的遞歸。

TL; 博士

當您更改分解順序時,您可以連續解鎖多個優化。

  • * 腳注:有一種特殊情況,OpenMP 優化將使用多個線程作為頂層,如果足夠小的話。 將 2x17 FFT 轉換為 17x2 FFT 將意味着不再使用第二個線程,但無論如何對於如此小的 FFT 來說這有點毫無意義。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM