[英]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 將被17x2
為17x2
而不是2x17
。 這似乎是一個微不足道的優化,但它確實允許我們刪除kf_bfly2
中的循環。 此外,它現在只使用第一個旋轉因子 - 這是一個非常方便的{1 + 0i}
。 所以kf_bfly2
唯一的乘法也被消除了。
優化並不止於此 - 因為kf_bfly2
現在小了很多,而且只有一個調用站點*,您的編譯器可能kf_bfly2
kf_work
內聯到kf_work
。 我們從改變的因式分解中知道2
只能是最后一個因數,因此我們也可以停止kf_work
的遞歸。
當您更改分解順序時,您可以連續解鎖多個優化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.