首页 > 解决方案 > 为什么kiss_fft 的正向和反向 radix-4 计算不同,第 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);

标签: cfftkissfft

解决方案


我确实可以使用该优化。但是,对于可以使用 AVX 的当前编译器来说,这不是必需的。他们也将使用vpcmpeqd and删除该分支vblendvps


推荐阅读