/alps/fwbench

To get this branch, use:
bzr branch http://darksoft.org/webbzr/alps/fwbench

« back to all changes in this revision

Viewing changes to fwbench.c

  • Committer: Suren A. Chilingaryan
  • Date: 2012-03-08 01:59:46 UTC
  • Revision ID: csa@dside.dyndns.org-20120308015946-x4jjv7zupjaj85n9
getopt support

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
#include <unistd.h>
10
10
#include <sys/stat.h>
11
11
#include <sys/time.h>
 
12
#include <getopt.h>
 
13
#include <stdarg.h>
12
14
 
13
15
#include <fastwriter.h>
14
16
 
19
21
#include "config.h"
20
22
 
21
23
//#define USE_FIFO
22
 
#define FW_BUFFER 4096l
23
24
#define WRITE_INTERVAL 1
24
25
#define WRITE_SUMMARY 5
25
26
#define DELTA_TOLERANCE 5
26
 
#define NEWFILE 10
27
27
 
28
28
#ifdef USE_UFO_GENERATOR
29
29
# ifndef USE_FIFO
31
31
# endif /* !USE_FIFO */
32
32
#endif /* USE_UFO_GENERATOR */
33
33
 
34
 
#define run_time 3600
35
34
const char *fifo_name = ".fifo";
36
35
 
37
36
struct setup_s {
40
39
    size_t bpp;
41
40
    size_t fps;
42
41
 
 
42
    size_t fpf;
43
43
    size_t iters;
 
44
    double tolerance;
 
45
    const char *output;
 
46
    const char *fs;
 
47
    
 
48
    int verbose;
44
49
 
45
50
    volatile int run_started;
46
51
 
58
63
    size_t writeouts;
59
64
    
60
65
    fastwriter_t *fw;
 
66
    char *current_output;
61
67
};
62
68
 
63
69
typedef struct setup_s setup_t;
64
70
 
65
71
 
 
72
 
 
73
typedef enum {
 
74
    OPT_OUTPUT = 'o',
 
75
    OPT_BUFFER = 'b',
 
76
    OPT_SIZE = 's',
 
77
    OPT_TIME = 't',
 
78
    OPT_RATE = 'r',
 
79
    OPT_FRAMES = 'n',
 
80
    OPT_GEOMETRY = 'g',
 
81
    OPT_FPF = 'f',
 
82
    OPT_MISSING = 'm',
 
83
    OPT_QUIET = 'q',
 
84
    OPT_HELP = 'h'
 
85
} options_t;
 
86
 
 
87
 
 
88
void Usage(int argc,  char* const argv[], const char *format, ...) {
 
89
    if (format) {
 
90
        va_list ap;
 
91
    
 
92
        va_start(ap, format);
 
93
        printf("Error %i: ", errno);
 
94
        vprintf(format, ap);
 
95
        printf("\n");
 
96
        va_end(ap);
 
97
    
 
98
        printf("\n");
 
99
    }
 
100
 
 
101
    printf(
 
102
"Usage:\n"
 
103
" %s [options]\n"
 
104
"   -o <file|device>    - Output to file/device [/dev/null]\n"
 
105
"                       use %%zu to replace with frame number\n"
 
106
"   -f <number>         - Number of frames per file [all]\n"
 
107
"   -b size             - Buffer Size (MB)\n"
 
108
"   -r rate             - Write rate (MB/s)\n"
 
109
"   -s size             - Total size of data to write (GB)\n"
 
110
"   -t run_time         - Run time (s)\n"
 
111
"   -n frames           - Number of frames to write\n"
 
112
"   -g <width>x<height> - Geometry [1024]\n"
 
113
"   -g <pixels>         - Number of megapixels [0.7]\n"
 
114
"   -m <percent>        - Tolerable missing frames  [100%%]\n"
 
115
"   -q                  - Quiete\n"
 
116
"   -h                  - Help\n"
 
117
"\n\n",
 
118
argv[0]);
 
119
 
 
120
    exit(0);
 
121
}
 
122
 
 
123
 
66
124
#ifdef USE_UFO_GENERATOR
67
125
static void handle_error(GError *error) {
68
126
    if (error != NULL) {
73
131
}
74
132
#endif /* USE_UFO_GENERATOR */
75
133
 
 
134
static void set_verbosity(setup_t *setup, int level) {
 
135
    setup->verbose = level;
 
136
}
 
137
 
 
138
static void set_current_output(setup_t *setup, size_t frame) {
 
139
    sprintf(setup->current_output, setup->output, frame);
 
140
}
 
141
 
 
142
static void set_output(setup_t *setup, const char *name) {
 
143
    setup->output = name;
 
144
    setup->fs = name;
 
145
    setup->current_output = malloc(strlen(setup->output) + 32);
 
146
    g_assert(setup->current_output);
 
147
    set_current_output(setup, 0);
 
148
}
76
149
 
77
150
static void set_dim(setup_t *setup, size_t width, size_t height) {
78
151
    setup->bpp = sizeof(float);
82
155
    setup->frame_size = setup->width * setup->height * setup->bpp;
83
156
}
84
157
 
 
158
static void set_pixels(setup_t *setup, size_t pixels) {
 
159
    int width = sqrt(4 * pixels / 3);
 
160
    set_dim(setup, width, width * 3 / 4);
 
161
}
 
162
 
85
163
static void set_speed(setup_t *setup, size_t speed) {
86
164
    setup->fps = 1 + speed / setup->width / setup->height / setup->bpp;
87
165
}
88
166
 
 
167
static void set_iters(setup_t *setup, size_t iters) {
 
168
    setup->iters = iters;
 
169
}
 
170
 
 
171
static void set_time(setup_t *setup, size_t run_time) {
 
172
    setup->iters = run_time * setup->fps;
 
173
}
 
174
 
89
175
static void set_size(setup_t *setup, size_t size) {
90
 
    setup->iters = size / setup->width / setup->height / setup->bpp;
91
 
}
92
 
 
93
 
static void set_time(setup_t *setup, size_t time) {
94
 
    setup->iters = time * setup->fps;
95
 
}
 
176
    setup->iters = size / setup->frame_size + (size % setup->frame_size)?1:0;
 
177
}
 
178
 
 
179
static void set_frames_per_file(setup_t *setup, size_t fpf) {
 
180
    setup->fpf = fpf;
 
181
}
 
182
 
 
183
static void set_fail_tolerance(setup_t *setup, double fail_rate) {
 
184
    setup->tolerance = fail_rate;
 
185
}
 
186
 
96
187
 
97
188
static int callback(setup_t *s, size_t result, void *buffer);
98
189
 
133
224
 
134
225
    ufo_graph_run(graph, &error);
135
226
    handle_error(error);
 
227
 
 
228
    g_thread_exit(NULL);
136
229
#else /* USE_UFO_GENERATOR */
137
230
    size_t i;
138
231
    struct timeval tv;
148
241
    int fd = open(fifo_name, O_WRONLY);
149
242
    g_assert(fd >= 0);
150
243
#endif /* USE_FIFO */
151
 
 
152
244
    gettimeofday(&tv, NULL); 
153
245
    nexts = tv.tv_sec;
154
246
    nextus = tv.tv_usec + interval;
177
269
 
178
270
#endif /* USE_UFO_GENERATOR */
179
271
 
180
 
    g_thread_exit(NULL);
181
272
    return NULL;
182
273
}
183
274
 
191
282
    size_t duration, last_duration, expected;
192
283
    long delta;
193
284
 
 
285
    gettimeofday(&tv, NULL);
194
286
 
195
287
    if (!s->broken_frame) {
196
288
        err = fastwriter_push(fw, result, buffer);
197
289
        if (err) {
198
290
            if (err == EWOULDBLOCK) {
 
291
                if (!s->tolerance) {
 
292
                    if (s->verbose >= 0) printf("Lost frame...\n");
 
293
                    exit(1);
 
294
                }
 
295
                
199
296
                if (s->num_read) fastwriter_cancel(fw);
200
297
                s->broken_frame = 1;
201
298
            } else {
217
314
    } else {
218
315
        err = fastwriter_commit(fw);
219
316
        s->frames++;
220
 
    }
221
 
 
222
 
    gettimeofday(&tv, NULL);
 
317
 
 
318
        if ((s->fpf)&&((s->frames%s->fpf) == 0)) {
 
319
            fastwriter_close(s->fw);
 
320
            set_current_output(s, s->frames);
 
321
            err = fastwriter_open(s->fw, s->current_output,  FASTWRITER_FLAGS_OVERWRITE);
 
322
            if (err) {
 
323
                printf("FastWriter returned error %i\n", err);
 
324
                g_assert(!err);
 
325
            }
 
326
 
 
327
        // reopen
 
328
    }
 
329
 
 
330
    }
 
331
    
223
332
    if (!s->tv_started.tv_sec) {
224
333
        memcpy(&s->tv_started, &tv, sizeof(struct timeval));
225
334
        if (s->tv_started.tv_usec >= (1000000 / s->fps)) 
235
344
    if (stats.buffer_used > s->buf_max) s->buf_max = stats.buffer_used;
236
345
 
237
346
    if ((tv.tv_sec - s->tv_last_written.tv_sec) >= WRITE_INTERVAL) {
238
 
        last_duration = (tv.tv_sec - s->tv_last_written.tv_sec) * 1000000 + (tv.tv_usec - s->tv_last_written.tv_usec);
239
 
 
240
 
        printf("Lost  %6.2lf%% (% 8lu of % 8lu), %9.3lf GB at %8.3lf MB/s, buf:%6.2lf%%\n", 100.*(s->lost - s->last_lost) / (s->lost + s->frames - s->last_lost - s->last_frames), s->lost - s->last_lost, s->lost + s->frames - (s->last_lost + s->last_frames), 1. * s->frame_size * (s->frames - s->last_frames) / 1024 / 1024 / 1024, 1000000. * s->frame_size * (s->frames - s->last_frames) / last_duration / 1024 / 1024, 100.*s->buf_max/stats.buffer_size);
 
347
        if ((s->tolerance > 0)&&(s->tolerance < 100)) {
 
348
            double lost = (100. * s->lost / (s->lost + s->frames));
 
349
            double last_lost = (100. * (s->lost - s->last_lost) / (s->lost + s->frames - s->last_lost - s->last_frames));
 
350
            if ((lost > s->tolerance)||(last_lost > s->tolerance)) {
 
351
                if (s->verbose >= 0)
 
352
                    printf("Lost %.2lf%% (%lu) frames, total: %.2lf%% (%lu)\n", last_lost, s->lost - s->last_lost, lost, s->lost);
 
353
                exit(1);
 
354
            }
 
355
        }
 
356
        
 
357
        if (s->verbose >= 0) {
 
358
            last_duration = (tv.tv_sec - s->tv_last_written.tv_sec) * 1000000 + (tv.tv_usec - s->tv_last_written.tv_usec);
 
359
            printf("Lost  %6.2lf%% (% 8lu of % 8lu), %9.3lf GB at %8.3lf MB/s, buf:%6.2lf%%\n", 100.*(s->lost - s->last_lost) / (s->lost + s->frames - s->last_lost - s->last_frames), s->lost - s->last_lost, s->lost + s->frames - (s->last_lost + s->last_frames), 1. * s->frame_size * (s->frames - s->last_frames) / 1024 / 1024 / 1024, 1000000. * s->frame_size * (s->frames - s->last_frames) / last_duration / 1024 / 1024, 100.*s->buf_max/stats.buffer_size);
 
360
        }
241
361
 
242
362
        if (((++s->writeouts)%WRITE_SUMMARY)==0) {
243
363
            duration = (tv.tv_sec - s->tv_started.tv_sec) * 1000000 + (tv.tv_usec - s->tv_started.tv_usec);
246
366
            if ((delta > DELTA_TOLERANCE)||(delta < -DELTA_TOLERANCE))
247
367
                printf(" *** Unexpected frame rate: %.2lf (%lu), delta: %li (%lu, %lu)\n", 1000000. * (s->frames + s->lost) / duration, s->fps, delta, s->lost + s->frames, expected); 
248
368
                
249
 
            printf("Total %6.2lf%% (% 8lu of % 8lu), %9.3lf GB at %8.3lf MB/s, buf:%6.2lf%%\n", 100. * s->lost / (s->lost + s->frames), s->lost, s->lost + s->frames, 1. * s->frames * s->frame_size / 1024 / 1024 / 1024, 1000000. * s->frames * s->frame_size / duration / 1024 / 1024,  100.*stats.buffer_max / stats.buffer_size);
 
369
            if (s->verbose >= 0) {
 
370
                printf("Total %6.2lf%% (% 8lu of % 8lu), %9.3lf GB at %8.3lf MB/s, buf:%6.2lf%%\n", 100. * s->lost / (s->lost + s->frames), s->lost, s->lost + s->frames, 1. * s->frames * s->frame_size / 1024 / 1024 / 1024, 1000000. * s->frames * s->frame_size / duration / 1024 / 1024,  100.*stats.buffer_max / stats.buffer_size);
 
371
            }
250
372
        }
251
373
        
252
374
        s->buf_max = 0;
259
381
}
260
382
 
261
383
 
262
 
int main(int argc, char const* argv[])
 
384
int main(int argc, char* const argv[])
263
385
{
264
386
    int err;
265
387
 
269
391
#endif /* USE_FIFO */
270
392
 
271
393
    setup_t setup;
 
394
 
 
395
    unsigned char c;
 
396
    const char *sptr;
272
397
    const char *out = "/dev/null";
 
398
    double mpix = 0;
273
399
    size_t width = 1024;
274
400
    size_t height = 768;
275
401
    size_t speed = 850;
 
402
    size_t size = 0;
 
403
    size_t run_time = 0;
 
404
    size_t iters = 0x7FFFFFFF;
 
405
    size_t fw_buffer = 0;
 
406
    double fail_rate = 100.;
 
407
    size_t fpf = 0;
 
408
    int quiet = 0;
 
409
    
276
410
 
277
 
    fastwriter_t *fw;
278
411
    fastwriter_stats_t stats;
279
412
 
280
413
    g_thread_init(NULL);
283
416
    g_type_init();
284
417
#endif /* USE_UFO_GENERATOR */
285
418
 
286
 
    if (argc > 1) {
287
 
        out = argv[1];
288
 
    }
289
 
    
290
 
    if (argc > 2) {
291
 
        speed = atoi(argv[2]);
 
419
 
 
420
 
 
421
    while ((c = getopt(argc, argv, "hqo:s:t:r:n:g:f:m:b:")) != (unsigned char)-1) {
 
422
        switch (c) {
 
423
         case OPT_OUTPUT:
 
424
            out = optarg;
 
425
            break;
 
426
         case OPT_BUFFER:
 
427
            fw_buffer = atol(optarg);
 
428
            break;
 
429
         case OPT_SIZE:
 
430
            size = atol(optarg);
 
431
            break;
 
432
         case OPT_TIME:
 
433
            run_time = atol(optarg);
 
434
            break;
 
435
         case OPT_FRAMES:
 
436
            iters = atol(optarg);
 
437
            break;
 
438
         case OPT_RATE:
 
439
            speed = atoi(optarg);
 
440
            break;
 
441
         case OPT_GEOMETRY:
 
442
            sptr = strchr(optarg, 'x');
 
443
            if (sptr) {
 
444
                width = atol(optarg);
 
445
                height = atol(sptr + 1);
 
446
            } else {
 
447
                mpix = atof(optarg);
 
448
            }
 
449
            break;
 
450
         case OPT_FPF:
 
451
            fpf = atol(optarg);
 
452
            break;
 
453
         case OPT_MISSING:
 
454
            fail_rate = atof(optarg);
 
455
            break;
 
456
        case OPT_QUIET:
 
457
            quiet = 1;
 
458
            break;
 
459
         case OPT_HELP:
 
460
            Usage(argc, argv, NULL);
 
461
     }
292
462
    }
293
463
 
294
464
#ifdef USE_FIFO
296
466
    g_assert(!mkfifo(fifo_name, S_IWUSR | S_IRUSR));
297
467
#endif /* USE_FIFO */
298
468
 
299
 
    fw = fastwriter_init(out, FASTWRITER_FLAGS_OVERWRITE);
300
 
    g_assert(fw);
301
 
    
302
 
    err = fastwriter_open(fw, out,  FASTWRITER_FLAGS_OVERWRITE);
 
469
 
 
470
    memset(&setup, 0, sizeof(setup_t));
 
471
 
 
472
    if (quiet) set_verbosity(&setup, -1);
 
473
    set_output(&setup, out);
 
474
    
 
475
    if (mpix) set_pixels(&setup, mpix * 1000000);
 
476
    else set_dim(&setup, width, height);
 
477
 
 
478
    set_speed(&setup, speed * 1024 * 1024);
 
479
 
 
480
    if (size) set_size(&setup, size * 1024 * 1024 * 1024);
 
481
    else if (run_time) set_time(&setup, run_time);
 
482
    else set_iters(&setup, iters);
 
483
    
 
484
    set_fail_tolerance(&setup, fail_rate);
 
485
    set_frames_per_file(&setup, fpf);
 
486
 
 
487
 
 
488
    setup.fw = fastwriter_init(setup.fs, FASTWRITER_FLAGS_OVERWRITE);
 
489
    g_assert(setup.fw);
 
490
 
 
491
    if (fw_buffer) 
 
492
        fastwriter_set_buffer_size(setup.fw, fw_buffer * 1024 * 1024);
 
493
    else
 
494
        fastwriter_set_buffer_size(setup.fw, FASTWRITER_BUFFER_MAX);
 
495
    
 
496
    err = fastwriter_open(setup.fw, setup.current_output,  FASTWRITER_FLAGS_OVERWRITE);
303
497
    if (err) printf("FastWriter returned error %i\n", err);
304
498
    g_assert(!err);
305
499
 
306
 
    fastwriter_set_buffer_size(fw, FW_BUFFER * 1024 * 1024);
307
 
    
308
 
    fastwriter_get_stats(fw, &stats);
309
 
 
310
 
    memset(&setup, 0, sizeof(setup_t));
311
 
 
312
 
    setup.fw = fw;
313
 
    set_dim(&setup, width, height);
314
 
    set_speed(&setup, speed * 1024 * 1024);
315
 
    set_size(&setup, run_time * speed * 1024 * 1024);
316
 
 
317
 
    printf("*** Writing to %s, rate: %lu, data: %lu MB/s, buffer: %lu MB\n", out, setup.fps, speed, stats.buffer_size);
 
500
 
 
501
    fastwriter_get_stats(setup.fw, &stats);
 
502
    if (!quiet)
 
503
        printf("*** Writing to %s, rate: %lu, data: %lu MB/s, buffer: %lu MB\n", out, setup.fps, speed, stats.buffer_size/1024/1024);
318
504
 
319
505
    void *buffer = malloc(setup.frame_size);
320
506
    g_assert(buffer);
345
531
#endif /* USE_FIFO */
346
532
 
347
533
    free(buffer);
348
 
    fastwriter_close(fw);
349
 
    fastwriter_destroy(fw);
 
534
    fastwriter_close(setup.fw);
 
535
    fastwriter_destroy(setup.fw);
350
536
 
351
537
#ifdef USE_FIFO
352
538
    unlink(fifo_name);