SoDaRadio-5.0.3-master:8901fb5
FFT_Test.cxx
Go to the documentation of this file.
1 /*
2 Copyright (c) 2012, Matthew H. Reilly (kb1vc)
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8 
9  Redistributions of source code must retain the above copyright
10  notice, this list of conditions and the following disclaimer.
11  Redistributions in binary form must reproduce the above copyright
12  notice, this list of conditions and the following disclaimer in
13  the documentation and/or other materials provided with the
14  distribution.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28 #define SAMPLE_RATE 48000
29 #include <complex>
30 #include <iostream>
31 #include <stdlib.h>
32 #include <time.h>
33 #include <fftw3.h>
34 #include <math.h>
35 #include <string.h>
36 #include <stdio.h>
37 #include <fcntl.h>
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 
41 using namespace std;
42 #include <sys/time.h>
43 
44 
45 // test program to compare the cost of various FFT vector sizes.
46 
47 using namespace std;
48 
49 double curtime()
50 {
51  double ret;
52  struct timeval tp;
53  gettimeofday(&tp, NULL);
54  ret = ((double) tp.tv_sec) + 1e-6*((double)tp.tv_usec);
55  return ret;
56 }
57 
58 complex<float> doWork(complex<float> * in, complex<float> * out, unsigned int vsize)
59 {
60  complex<float> ret(0.0,0.0);
61  // create a plan.
62  fftwf_plan plan = fftwf_plan_dft_1d(vsize, (fftwf_complex*) in, (fftwf_complex*) out,
63  FFTW_FORWARD, FFTW_ESTIMATE);
64 
65  // timestamp
66  double startt = curtime();
67 
68  // do 100 FFTs
69  for(int i = 0; i < 100; i++) {
70  fftwf_execute(plan);
71  ret += out[3];
72  }
73  // timestamp
74  double endt = curtime();
75 
76  //report
77  double ttime = (endt - startt)/100;
78  double time_per_point = ttime / ((double) vsize);
79  printf("%d %g %g\n", vsize, ttime, time_per_point);
80 
81  // destroy plan
82  fftwf_destroy_plan(plan);
83 
84  return ret;
85 }
86 
87 int main(int argc, char * argv[])
88 {
89  (void) argc; (void) argv;
90  // try various sizes of FFT inputs from powers of two between 8 and 32K
91  // and for multiples of 2^N * 3 from 48 through 49152 (48 * 1024)
92 
93  static int maxbuf = 1000000;
94  complex<float> * invec; // really big buffers
95  complex<float> * outvec;
96 
97  invec = (complex<float>*) fftwf_malloc(maxbuf * sizeof(complex<float>));
98  outvec = (complex<float>*) fftwf_malloc(maxbuf * sizeof(complex<float>));
99 
100  // fill in the input vector;
101  float anginc = M_PI * 20.0;
102  float ang = 0.0;
103  int i;
104  for(i = 0; i < maxbuf; i++) {
105  invec[i] = complex<float>(cos(ang), sin(ang));
106  ang += anginc;
107  if(ang > M_PI) ang -= (2.0 * M_PI);
108  }
109 
110  // now create and destroy plans. Start with powers of two.
111  unsigned int vecsize;
112  complex<float> rsum(0.0,0.0);
113  for(vecsize = 32; vecsize <= 50000; vecsize *= 2) {
114  rsum += doWork(invec, outvec, vecsize);
115  }
116  for(vecsize = 48; vecsize <= 50000; vecsize *= 2) {
117  rsum += doWork(invec, outvec, vecsize);
118  }
119  unsigned int ivs[] = { 625, 1250, 2500, 3125, 5000, 15625, 78125, 390625, 0 };
120  for(i = 0; ivs[i] > 0; i++) {
121  rsum += doWork(invec, outvec, ivs[i]);
122  }
123  rsum += doWork(invec, outvec, 30000 + 1250);
124  rsum += doWork(invec, outvec, 30000);
125  rsum += doWork(invec, outvec, 32768);
126  rsum += doWork(invec, outvec, 48 * 48);
127 
128  // now for buffer copy cost...
129  double startt = curtime();
130  for(i = 0; i < 100; i++) {
131  memcpy(invec, outvec, 30000 * sizeof(complex<float>));
132  rsum += invec[i];
133  invec[i*2] *= rsum;
134  memcpy(outvec, invec, 30000 * sizeof(complex<float>));
135  rsum += outvec[i+3];
136  outvec[i*2+3] *= rsum;
137  }
138  double endt = curtime();
139  double timet = endt - startt;
140 
141  printf("memcpy bandwidth %g sec for a 30K long vector, %g sec per sample.\n",
142  timet / 200.0, timet / (200.0 * 30000.0));
143 
144  printf("dummy print = %f %f\n", rsum.real(), rsum.imag());
145 }
double curtime()
Definition: FFT_Test.cxx:49
int main(int argc, char *argv[])
Definition: FFT_Test.cxx:87
STL namespace.
complex< float > doWork(complex< float > *in, complex< float > *out, unsigned int vsize)
Definition: FFT_Test.cxx:58