1 /************************************************************************
3 IMPORTANT NOTE : this file contains two clearly delimited sections :
4 the ARCHITECTURE section (in two parts) and the USER section. Each section
5 is governed by its own copyright and license. Please check individually
6 each section for license and copyright information.
7 *************************************************************************/
9 /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
11 /************************************************************************
12 FAUST Architecture File
13 Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
14 ---------------------------------------------------------------------
15 This Architecture section is free software; you can redistribute it
16 and/or modify it under the terms of the GNU General Public License
17 as published by the Free Software Foundation; either version 3 of
18 the License, or (at your option) any later version.
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with this program; If not, see <http://www.gnu.org/licenses/>.
28 EXCEPTION : As a special exception, you may create a larger work
29 that contains this FAUST architecture section and distribute
30 that work under terms of your choice, so long as this FAUST
31 architecture section is not modified.
34 ************************************************************************
35 ************************************************************************/
48 #include <sys/ioctl.h>
52 #include <sys/types.h>
67 // On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
68 // flags to avoid costly denormals
70 #include <xmmintrin.h>
72 #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
74 #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
77 #define AVOIDDENORMALS
80 struct Meta
: map
<const char*, const char*>
82 void declare (const char* key
, const char* value
) { (*this)[key
]=value
; }
87 float* gBuffer
= 0; // a buffer of NV*VSize samples
89 unsigned int COUNT
= 2000; // number of measures
90 unsigned int NV
= 4096; // number of vectors in BIG buffer (should exceed cache)
91 unsigned int ITER
= 10; // number of iterations per measure
92 unsigned int VSIZE
= 4096; // size of a vector in samples
93 unsigned int IDX
= 0; // current vector number (0 <= VIdx < NV)
96 //inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((unsigned)(calloc((nmemb*size)+15,sizeof(char)))+15 & 0xfffffff0); }
97 //inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((size_t)(calloc((nmemb*size)+15,sizeof(char)))+15 & ~15); }
101 // g++ -Wall -O3 -lm -lpthread -lasound `gtk-config --cflags --libs` test.cpp -o test
104 //-------------------------------------------------------------------
105 // Generic min and max using c++ inline
106 //-------------------------------------------------------------------
108 inline int max (unsigned int a
, unsigned int b
) { return (a
>b
) ? a
: b
; }
109 inline int max (int a
, int b
) { return (a
>b
) ? a
: b
; }
111 inline long max (long a
, long b
) { return (a
>b
) ? a
: b
; }
112 inline long max (int a
, long b
) { return (a
>b
) ? a
: b
; }
113 inline long max (long a
, int b
) { return (a
>b
) ? a
: b
; }
115 inline float max (float a
, float b
) { return (a
>b
) ? a
: b
; }
116 inline float max (int a
, float b
) { return (a
>b
) ? a
: b
; }
117 inline float max (float a
, int b
) { return (a
>b
) ? a
: b
; }
118 inline float max (long a
, float b
) { return (a
>b
) ? a
: b
; }
119 inline float max (float a
, long b
) { return (a
>b
) ? a
: b
; }
121 inline double max (double a
, double b
) { return (a
>b
) ? a
: b
; }
122 inline double max (int a
, double b
) { return (a
>b
) ? a
: b
; }
123 inline double max (double a
, int b
) { return (a
>b
) ? a
: b
; }
124 inline double max (long a
, double b
) { return (a
>b
) ? a
: b
; }
125 inline double max (double a
, long b
) { return (a
>b
) ? a
: b
; }
126 inline double max (float a
, double b
) { return (a
>b
) ? a
: b
; }
127 inline double max (double a
, float b
) { return (a
>b
) ? a
: b
; }
130 inline int min (int a
, int b
) { return (a
<b
) ? a
: b
; }
132 inline long min (long a
, long b
) { return (a
<b
) ? a
: b
; }
133 inline long min (int a
, long b
) { return (a
<b
) ? a
: b
; }
134 inline long min (long a
, int b
) { return (a
<b
) ? a
: b
; }
136 inline float min (float a
, float b
) { return (a
<b
) ? a
: b
; }
137 inline float min (int a
, float b
) { return (a
<b
) ? a
: b
; }
138 inline float min (float a
, int b
) { return (a
<b
) ? a
: b
; }
139 inline float min (long a
, float b
) { return (a
<b
) ? a
: b
; }
140 inline float min (float a
, long b
) { return (a
<b
) ? a
: b
; }
142 inline double min (double a
, double b
) { return (a
<b
) ? a
: b
; }
143 inline double min (int a
, double b
) { return (a
<b
) ? a
: b
; }
144 inline double min (double a
, int b
) { return (a
<b
) ? a
: b
; }
145 inline double min (long a
, double b
) { return (a
<b
) ? a
: b
; }
146 inline double min (double a
, long b
) { return (a
<b
) ? a
: b
; }
147 inline double min (float a
, double b
) { return (a
<b
) ? a
: b
; }
148 inline double min (double a
, float b
) { return (a
<b
) ? a
: b
; }
151 inline int lsr (int x
, int n
) { return int(((unsigned int)x
) >> n
); }
154 bool setRealtimePriority ()
160 struct sched_param param
;
163 pw
= getpwnam ("root");
166 pthread_getschedparam(pthread_self(), &policy
, ¶m
);
168 param
.sched_priority
= 50;
169 err
= pthread_setschedparam(pthread_self(), policy
, ¶m
);
175 #include <sys/time.h>
183 i
= gettimeofday(&tp
,&tzp
);
184 return ( (double) tp
.tv_sec
+ (double) tp
.tv_usec
* 1.e
-6 );
187 /******************************************************************************
188 *******************************************************************************
192 *******************************************************************************
193 *******************************************************************************/
201 /******************************************************************************
202 *******************************************************************************
204 ABSTRACT USER INTERFACE
206 *******************************************************************************
207 *******************************************************************************/
214 UI() : fStopped(false) {}
217 virtual void addButton(const char* label
, float* zone
) = 0;
218 virtual void addToggleButton(const char* label
, float* zone
) = 0;
219 virtual void addCheckButton(const char* label
, float* zone
) = 0;
220 virtual void addVerticalSlider(const char* label
, float* zone
, float init
, float min
, float max
, float step
) = 0;
221 virtual void addHorizontalSlider(const char* label
, float* zone
, float init
, float min
, float max
, float step
) = 0;
222 virtual void addNumEntry(const char* label
, float* zone
, float init
, float min
, float max
, float step
) = 0;
224 // -- passive widgets
226 virtual void addNumDisplay(const char* label
, float* zone
, int precision
) = 0;
227 virtual void addTextDisplay(const char* label
, float* zone
, char* names
[], float min
, float max
) = 0;
228 virtual void addHorizontalBargraph(const char* label
, float* zone
, float min
, float max
) = 0;
229 virtual void addVerticalBargraph(const char* label
, float* zone
, float min
, float max
) = 0;
231 virtual void openFrameBox(const char* label
) = 0;
232 virtual void openTabBox(const char* label
) = 0;
233 virtual void openHorizontalBox(const char* label
) = 0;
234 virtual void openVerticalBox(const char* label
) = 0;
236 virtual void closeBox() = 0;
238 virtual void run() = 0;
240 void stop() { fStopped
= true; }
241 bool stopped() { return fStopped
; }
243 virtual void declare(float* zone
, const char* key
, const char* value
) {}
249 /******************************************************************************
250 *******************************************************************************
254 *******************************************************************************
255 *******************************************************************************/
259 //----------------------------------------------------------------
260 // definition du processeur de signal
261 //----------------------------------------------------------------
269 virtual int getNumInputs() = 0;
270 virtual int getNumOutputs() = 0;
271 virtual void buildUserInterface(UI
* interface
) = 0;
272 virtual void init(int samplingRate
) = 0;
273 virtual void compute(int len
, float** inputs
, float** outputs
) = 0;
276 /********************END ARCHITECTURE SECTION (part 1/2)****************/
278 /**************************BEGIN USER SECTION **************************/
282 /***************************END USER SECTION ***************************/
284 /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
291 static __inline__
unsigned long long int rdtsc(void)
293 unsigned long long int x
;
294 __asm__
volatile (".byte 0x0f, 0x31" : "=A" (x
));
301 * Bench by calling COUNT times the compute() method for
302 * the computation of vsize samples
305 #define MEGABYTE 1048576.0
307 void statistic(const char* name
, double* timing
)
310 double mega
= double(VSIZE
*ITER
)/MEGABYTE
; // mega samples
311 // skip first 10 values to avoid cache bias ???
312 lo
= hi
= tot
= mega
/(timing
[11] - timing
[10]);
313 for (int i
= 11; i
<COUNT
; i
++) {
314 double delta
= mega
/(timing
[i
] - timing
[i
-1]);
317 } else if (delta
> hi
) {
324 << '\t' << hi
*4*DSP
.getNumInputs() << '\t' << "MB/s inputs"
325 << '\t' << hi
*4*DSP
.getNumOutputs() << '\t' << "MB/s outputs"
326 << '\t' << tot
/(COUNT
-11)
333 unsigned int BSIZE
= NV
* VSIZE
;
334 gBuffer
= (float*) calloc (BSIZE
, sizeof(float));
337 for (int j
= 0; j
< BSIZE
; j
++) {
338 int R0temp0
= (12345 + (1103515245 * R0_0
));
339 gBuffer
[j
] = 4.656613e-10f
*R0temp0
;
347 return &gBuffer
[IDX
*VSIZE
];
350 void bench(const char* name
)
353 int numInChan
= DSP
.getNumInputs();
354 int numOutChan
= DSP
.getNumOutputs();
356 assert (numInChan
< 256);
357 assert (numOutChan
< 256);
359 float* inChannel
[256];
360 float* outChannel
[256];
362 // allocate input buffers (initialized with white noise)
365 // allocate output channels (not initialized)
366 for (int i
= 0; i
< numOutChan
; i
++) outChannel
[i
] = (float*) calloc (VSIZE
, sizeof(float));
368 // init the dsp with a resoneable sampling rate)
370 double* timing
= (double*) calloc (COUNT
, sizeof(double));
372 for (int i
= 0; i
<COUNT
; i
++) {
373 timing
[i
] = mysecond();
374 for (int k
= 0; k
<ITER
; k
++) {
375 // allocate new input buffers to avoid L2 cache
376 for (int c
=0; c
<numInChan
; c
++) { inChannel
[c
] = nextVect(); }
377 DSP
.compute(VSIZE
,inChannel
,outChannel
);
381 statistic(name
, timing
);
384 //-------------------------------------------------------------------------
386 //-------------------------------------------------------------------------
388 // lopt : Scan Command Line long int Arguments
390 long lopt (int argc
, char *argv
[], const char* longname
, const char* shortname
, long def
)
392 for (int i
=2; i
<argc
; i
++)
393 if ( strcmp(argv
[i
-1], shortname
) == 0 || strcmp(argv
[i
-1], longname
) == 0 )
394 return atoi(argv
[i
]);
399 int main(int argc
, char *argv
[] )
402 VSIZE
= lopt(argc
, argv
, "--vector-size", "-vec", 4096);
403 NV
= lopt(argc
, argv
, "--num-vector", "-n", 20000);
404 COUNT
= lopt(argc
, argv
, "--count", "-c", 1000);
405 ITER
= lopt(argc
, argv
, "--iteration", "-i", 10);
406 //setRealtimePriority();
412 /********************END ARCHITECTURE SECTION (part 2/2)****************/