int main(int argc, char *argv[]) { int x=-1; srand(0); if(argc<2){ fprintf(stderr, "Specify log2 of transform size."); exit(1); } if(argc>2) x=atoi(argv[2]); tbb::task_scheduler_init init(x); int log2n=atoi(argv[1]); int n=1<<log2n; std::vector<std::complex<double> > in(n, 0.0), in_tbb(n, 0.0), in_opt(n, 0.0), in_seq(n, 0.0), out(n), out_tbb(n), out_opt(n), out_seq(n); for(int j=0;j<n;j++){ in[j]=std::complex<double>(rand()/(double)(RAND_MAX) - 0.5, rand()/(double)(RAND_MAX) - 0.5); } fft(n, &in[0], &out[0]); //warmup run tbb::tick_count serial_start = tbb::tick_count::now(); for (int i = 0; i < ITER; ++i) fft(n, &in[0], &out[0]); tbb::tick_count serial_end = tbb::tick_count::now(); std::cout << (serial_end - serial_start).seconds()/ITER << std::endl; if (!(check(n, &out[0] ,&out[0]))) //check against original results for correct result std::cout << "Error in original code!" << std::endl; fft_tbb(n, &in[0], &out_tbb[0]); //warmup run tbb::tick_count tbb_start = tbb::tick_count::now(); for (int i = 0; i < ITER; ++i) fft_tbb(n, &in[0], &out_tbb[0]); tbb::tick_count tbb_end = tbb::tick_count::now(); std::cout << (tbb_end - tbb_start).seconds()/ITER << std::endl; if (!(check(n, &out[0] ,&out_tbb[0]))) //check against original results for correct result std::cout << "Error in original code!" << std::endl; fft_opt(n, &in[0], &out_opt[0]); //warmup run tbb::tick_count opt_start = tbb::tick_count::now(); for (int i = 0; i < ITER; ++i) fft_opt(n, &in[0], &out_opt[0]); tbb::tick_count opt_end = tbb::tick_count::now(); std::cout << (opt_end - opt_start).seconds()/ITER << std::endl; if (!(check(n, &out[0] ,&out_opt[0]))) //check against original results for correct result std::cout << "Error in original code!" << std::endl; fft_seq(n, &in[0], &out_seq[0]); //warmup run tbb::tick_count seq_start = tbb::tick_count::now(); for (int i = 0; i < ITER; ++i) fft_seq(n, &in[0], &out_seq[0]); tbb::tick_count seq_end = tbb::tick_count::now(); std::cout << (seq_end - seq_start).seconds()/ITER << std::endl; if (!(check(n, &out[0] ,&out_seq[0]))) //check against original results for correct result std::cout << "Error in original code!" << std::endl; /* To test this, you can try loading the output into matlab. Load the output as a four column matrix x. Then the input is: in=x(:,1)+x(:,2)*i and the output is: out=x(:,3)+x(:,4)*i You can then do fft(in) to check what matlab thinks it should be. Note that this fft and matlab fft produce outputs in different orders. How could you "sort" (hint-hing) that out in matlab so that you can check you have the same spectrum. You can also try putting in various types of sine wave, and checking whether you get the right frequency peaks in the output. You're the signal processing experts, I assume you know what a fourier transform does. Note that this not a very accurate fft, so you should expect the error to grow as the transform size grows. */ return 0; }
int main(int argc, char *argv[]) { srand(0); if(argc<3){ fprintf(stderr, "Specify log2 of transform size and number of available cores (>1)"); // hold terminal (windows) cin.get(); exit(1); } int log2n=atoi(argv[1]); unsigned int n=1<<log2n; int count = 1; if(argv[3]) { // facility to set number of times to run each // version and take mean. Useful for scripting // of the running/data collection count = atoi(argv[3]); } // Set number of cores from args CoresInformation::setCores(atoi(argv[2])); vector<complex<double> > in(n, 0.0), out(n), out_tbb(n), out_opt(n), out_seq(n); for(unsigned j=0;j<n;j++){ in[j]=complex<double>(rand()/(double)(RAND_MAX) - 0.5, rand()/(double)(RAND_MAX) - 0.5); } double time_fft(0), time_tbb(0), time_opt(0), time_seq(0); int count_fft, count_tbb, count_opt, count_seq; count_fft = count_tbb = count_opt = count_seq = count; // original for(int i = 0; i < count; i++) { tick_count start_fft = tick_count::now(); fft(n, &in[0], &out[0]); tick_count end_fft = tick_count::now(); time_fft += (end_fft-start_fft).seconds(); } cout << time_fft/count << endl; // tbb enabled for(int i = 0; i < count; i++) { tick_count start_tbb = tick_count::now(); fft_tbb(n, &in[0], &out_tbb[0]); tick_count end_tbb = tick_count::now(); time_tbb += (end_tbb-start_tbb).seconds(); } cout << time_tbb/count << endl; // tbb optimised for(int i = 0; i < count; i++) { tick_count start_opt = tick_count::now(); fft_opt(n, &in[0], &out_opt[0]); tick_count end_opt = tick_count::now(); time_opt += (end_opt-start_opt).seconds(); } cout << time_opt/count << endl; // sequential for(int i = 0; i < count; i++) { tick_count start_seq = tick_count::now(); fft_seq(n, &in[0], &out_seq[0]); tick_count end_seq = tick_count::now(); time_seq += (end_seq-start_seq).seconds(); } cout << time_seq/count << endl; // check outputs were all the same as the original code for(unsigned j=0;j<n;j++){ if (real(out[j]) != real(out_tbb[j]) || abs(imag(out[j]) - imag(out_tbb[j])) > 0.01) cout << "error in tbb code" << endl; if (real(out[j]) != real(out_opt[j]) || abs(imag(out[j]) - imag(out_opt[j])) > 0.01) cout << "error in opt code" << endl; } /* To test this, you can try loading the output into matlab. Load the output as a four column matrix x. Then the input is: in=x(:,1)+x(:,2)*i and the output is: out=x(:,3)+x(:,4)*i You can then do fft(in) to check what matlab thinks it should be. Note that this fft and matlab fft produce outputs in different orders. How could you "sort" (hint-hing) that out in matlab so that you can check you have the same spectrum. You can also try putting in various types of sine wave, and checking whether you get the right frequency peaks in the output. You're the signal processing experts, I assume you know what a fourier transform does. Note that this not a very accurate fft, so you should expect the error to grow as the transform size grows. */ return 0; }