//-------------------------------------------------------------------------------- // Programme d'exemple multi-threads de FFT par paquet // Test BAO-Radio/Acq // R. Ansari - C. Magneville , Decembre 2007 // Exemples de commandes pour test (dans l'ordre ci-dessous : // csh> tmtfft VSZ NTH NbFFT [PaqSz=4096] // csh> tmtfft 1310720 1 10000 16384 // csh> tmtfft 1310720 1 10000 8192 // csh> tmtfft 1310720 2 10000 8192 //-------------------------------------------------------------------------------- #include "sopnamsp.h" #include "zthread.h" #include "resusage.h" #include "ctimer.h" #include "timing.h" #include #include #include #include #include #include "tvector.h" #include "fioarr.h" #include "matharr.h" #include "tarrinit.h" #include "randfmt.h" #include "fftpserver.h" #include "fftwserver.h" #include "FFTW/fftw3.h" //--------------------------------------------------------------------------------- // Definition d'une classe heritant de ZThread, pour remplir un vecteur avec // des aleatoires class MTDoFFT : public ZThread { public: MTDoFFT(TVector& v, sa_size_t nfft=10, sa_size_t paqsz=4096); virtual void run(); inline TVector& getSpectre() { return spectre_; } protected: string nom_; TVector vv_; sa_size_t nbfft_; // Nb de FFT a faire sa_size_t paqsz_; // taille des paquets pour FFT TVector spectre_; // spectre moyenne TVector< complex > cfour_; // composant TF FFTPackServer ffts_; // serveur FFT }; static int mtrandId = 0; // Pour donner un identificateur a chaque thread ZMutex* pmtx_=NULL; // pour synchroniser creation de plan_fftw; MTDoFFT::MTDoFFT(TVector& v, sa_size_t nfft, sa_size_t paqsz) : vv_(v,true), // Partage de reference du vecteur nbfft_(nfft), paqsz_(paqsz), ffts_(true) // preserve input=true { if (pmtx_==NULL) pmtx_ = new ZMutex; char buff[32]; sprintf(buff, "MTDoFFT-Id=%d", mtrandId); mtrandId++; nom_ = buff; // Initialisation taille vecteurs TVector vx(paqsz_); vx = RegularSequence(); ffts_.FFTForward(vx, cfour_); spectre_.ReSize(cfour_.Size()); cout << " Thread MTDoFFT(" << nom_ << ", PaqSz=" << paqsz_ << " ) Created ... " << endl; } inline r_4 Zmod2(complex z) { return (z.real()*z.real()+z.imag()*z.imag()); } // Le travail fait dans chaque thread (appele par start()) void MTDoFFT::run() { Timer tm(nom_.c_str()); cout << "MTDoFFT::run() - Nom= " << nom_ << " vv.Size()= " << vv_.Size() << " PaqSz=" << paqsz_ << " NbFFT= " << nbfft_ << endl; FMTRandGen rgen; TVector vx(paqsz_); pmtx_->lock(); fftwf_plan plan = fftwf_plan_dft_r2c_1d(paqsz_, vx.Data(), (fftwf_complex *)cfour_.Data(), FFTW_ESTIMATE); pmtx_->unlock(); sa_size_t prm = nbfft_/10; for(sa_size_t i=0; i vx = vv_(Range(first,last)); fftwf_execute(plan); // ffts_.FFTForward(vx, cfour_); // for(sa_size_t j=0; j vth; FMTRandGen rg; TVector DATA(VSZ); for(sa_size_t i=0; istart(); cout << "[4] f3_tmtfft/waiting for all threads to finish " << endl; sleep(1); for(int kt=0; ktjoin(); tm.Split("Threads-Finished"); cout << "[5] f3_tmtfft/saving spectra to file mtspectra.ppf " << endl; POutPersist po("mtspectra.ppf"); for(int kt=0; ktgetSpectre(); cout << "[6] f3_tmtfft/deleting thread objects " << endl; for(int kt=0; kt 4) paqsz = atoi(arg[4]); try { f3_tmtfft(VSZ, NTH, nfft, paqsz); } catch (PThrowable exc) { cerr << "tmtfft: catched Exception " << exc.Msg() << endl; rc = 77; } catch (...) { cerr << " catched unknown (...) exception (tmtfft.cc) " << endl; rc = 78; } cout << "----------- tmtfft/END ------- " << endl; PrtTim("---END tmtfft---"); return(rc); }