[英]Why is the kiss_fft's forward and inverse radix-4 calculation different, part 2?
第 1 部分 - 為什么下面的代碼首先檢查 st_inverse
Kiss_fft 代碼在循環中有這個分支:
do {
if(st->inverse) {
Fout[m].r = scratch[5].r - scratch[4].i;
Fout[m].i = scratch[5].i + scratch[4].r;
Fout[m3].r = scratch[5].r + scratch[4].i;
Fout[m3].i = scratch[5].i - scratch[4].r;
}else{
Fout[m].r = scratch[5].r + scratch[4].i;
Fout[m].i = scratch[5].i - scratch[4].r;
Fout[m3].r = scratch[5].r - scratch[4].i;
Fout[m3].i = scratch[5].i + scratch[4].r;
}
++Fout;
} while (--k); // Fout[] has k*4 elements.
稍微重新排序:
if(st->inverse) {
Fout[m].r = scratch[5].r - scratch[4].i;
Fout[m].i = scratch[5].i + scratch[4].r;
Fout[m3].r = scratch[5].r + scratch[4].i;
Fout[m3].i = scratch[5].i - scratch[4].r;
}else{
Fout[m3].r = scratch[5].r - scratch[4].i;
Fout[m3].i = scratch[5].i + scratch[4].r
Fout[m].r = scratch[5].r + scratch[4].i;
Fout[m].i = scratch[5].i - scratch[4].r;;
}
這兩個代碼塊的真正區別僅在於它們對m
和m3
。 但是m
和m3
在循環內沒有改變。 我可以通過交換m
和m3
簡單地消除這個內循環分支嗎?
if(st->inverse) { swap(&m, &m3); }
do {
Fout[m].r = scratch[5].r - scratch[4].i;
Fout[m].i = scratch[5].i + scratch[4].r;
Fout[m3].r = scratch[5].r + scratch[4].i;
Fout[m3].i = scratch[5].i - scratch[4].r;
++Fout;
} while (--k);
我確實可以使用這種優化。 但是,對於可以使用 AVX 的當前一代編譯器,這不是必需的。 他們也會使用vpcmpeqd
和vblendvps
消除該分支。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.