这段FFT程序用递归为什么多线程反而慢于单线程

发布于 2022-09-02 23:50:13 字数 3170 浏览 13 评论 0

用C++和递归实现FFT,代码改对了,可是如果设置border=128,递归调用线程,取样128个数,执行1000次,时间500ms左右,border=64的话时间大约700ms,而直接单线程则只用200ms,是线程的构造函数耗时太长的缘故吗?

#define border 128

template<class iter, class outputIter>
inline void FFT(iter first, iter last, outputIter res)
{
    int n=std::distance(first,last);
    int N=n/2;
    const double PI=3.14159265358979323846;
    if(n!=2){

        complex* temp1=new complex[N];
        complex* temp2=new complex[N];
        complex* out1=new complex[N];
        complex* out2=new complex[N];
        for(int i=0;i<N;++i){
            temp1[i]=*first;
            ++first;
            temp2[i]=*first;
            ++first;
        }
        const complex J(0,1);
        complex w=exp(-2.0*PI*J/(double) n);
        complex wk=1;
        
        if(n>=border){
            std::thread t2([temp2,out2,&N](){FFT(temp2,temp2+N,out2);});
            FFT(temp1,temp1+N,out1);
            delete [] temp1;
            t2.join();
            delete [] temp2;
        }
        
        else{
            FFT(temp1,temp1+N,out1);
            FFT(temp2,temp2+N,out2);
            delete [] temp1;
            delete [] temp2;
        }
        
        for(int k=0;k<N;k++){
            *res=(out1[k]+wk*out2[k]);
            wk*=w;
            ++res;
        }
        wk=1;
        for(int k=0;k<N;k++){
            *res=(out1[k]-wk*out2[k]);
            wk*=w;
            ++res;
        }
        delete [] out1; delete [] out2;
    }
    
    
    else{
        complex y1=*first;
        ++first;
        complex y2=*first;
        *res=(y1+y2);
        ++res;
        *res=(y1-y2);
    }
}


template<class iter, class outputIter>
inline void IFFT(iter first, iter last, outputIter res)
{
    int n=std::distance(first,last);
    int N=n/2;
    double s=.5;
    const double PI=3.14159265358979323846;
    if(n!=2){
        complex* temp1=new complex[N];
        complex* temp2=new complex[N];
        complex* out1=new complex[N];
        complex* out2=new complex[N];
        for(int i=0;i<N;++i){
            temp1[i]=*first;
            ++first;
            temp2[i]=*first;
            ++first;
        }
        const complex J(0,1);
        complex w=exp(2.0*PI*J/(double) n);
        complex wk=1.0;
        
        if(n>=border){
            std::thread t2([temp2,out2,&N](){IFFT(temp2,temp2+N,out2);});
            IFFT(temp1,temp1+N,out1);
            delete [] temp1;
            t2.join();
            delete [] temp2;
        }
        
        else{
            IFFT(temp1,temp1+N,out1);
            IFFT(temp2,temp2+N,out2);
            delete [] temp1;
            delete [] temp2;
        }
        
        for(int k=0;k<N;k++){
            *res=s*(out1[k]+wk*out2[k]);
            wk*=w;
            ++res;
        }
        wk=1.0;
        for(int k=0;k<N;k++){
            *res=s*(out1[k]-wk*out2[k]);
            wk*=w;
            ++res;
        }
        delete [] out1; delete [] out2;
    }
    
    
    else{
        complex y1=*first;
        ++first;
        complex y2=*first;
        *res=s*(y1+y2);
        ++res;
        *res=s*(y1-y2);
    }
}


如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

裸钻 2022-09-09 23:50:13

多线程在任务量越大的情况下效果才越明显。量小时,线程的创建和切换带来的时间消耗会大于并行计算节省的时间。就像1000个人造一间房子不一定比10个人造一间房子快,而1000个人造100间房子就会比10个人快。

佼人 2022-09-09 23:50:13

我建议可以在你觉得可疑的代码块或函数前后打印时间,这样你就能看出耗时的地方究竟在哪里。
然后再分析为什么耗时。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文