/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-07 21:22:03 UTC
  • Revision ID: csa@dside.dyndns.org-20120307212203-tmgttt1yyn38dny8
Use local data generator until high-speed ufo simulator is provided

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#define _BSD_SOURCE
1
2
#include <stdio.h>
2
3
#include <stdlib.h>
3
4
#include <string.h>
10
11
#include <sys/time.h>
11
12
 
12
13
#include <fastwriter.h>
13
 
#include <ufo/ufo-graph.h>
 
14
 
 
15
#ifdef USE_UFO_GENERATOR
 
16
# include <ufo/ufo-graph.h>
 
17
#endif /* USE_UFO_GENERATOR */
14
18
 
15
19
#include "config.h"
16
20
 
 
21
//#define USE_FIFO
17
22
#define FW_BUFFER 4096l
18
23
#define WRITE_INTERVAL 1
19
24
#define WRITE_SUMMARY 5
 
25
#define DELTA_TOLERANCE 5
20
26
#define NEWFILE 10
21
27
 
 
28
#ifdef USE_UFO_GENERATOR
 
29
# ifndef USE_FIFO
 
30
#  define USE_FIFO
 
31
# endif /* !USE_FIFO */
 
32
#endif /* USE_UFO_GENERATOR */
22
33
 
23
34
#define run_time 3600
24
35
const char *fifo_name = ".fifo";
28
39
    size_t height;
29
40
    size_t bpp;
30
41
    size_t fps;
31
 
    
 
42
 
32
43
    size_t iters;
33
44
 
34
45
    volatile int run_started;
 
46
 
 
47
    struct timeval tv_started;
 
48
    struct timeval tv_last_written;
 
49
 
 
50
    int broken_frame;
 
51
    unsigned long frames, lost;
 
52
    unsigned long last_frames, last_lost;
 
53
 
 
54
    size_t frame_size;
 
55
    size_t num_read;
 
56
    size_t buf_max;
 
57
    
 
58
    size_t writeouts;
 
59
    
 
60
    fastwriter_t *fw;
35
61
};
36
62
 
37
63
typedef struct setup_s setup_t;
38
64
 
39
 
void handle_error(GError *error) {
 
65
 
 
66
#ifdef USE_UFO_GENERATOR
 
67
static void handle_error(GError *error) {
40
68
    if (error != NULL) {
41
69
        g_print("%s\n", error->message); 
42
70
        g_error_free(error);
43
71
        exit(EXIT_FAILURE);
44
72
    }
45
73
}
46
 
 
47
 
void set_speed(setup_t *setup, size_t speed) {
 
74
#endif /* USE_UFO_GENERATOR */
 
75
 
 
76
 
 
77
static void set_dim(setup_t *setup, size_t width, size_t height) {
48
78
    setup->bpp = sizeof(float);
49
 
    setup->width = 1024;
50
 
    setup->height = 768;
 
79
    setup->width = width;
 
80
    setup->height = height;
 
81
 
 
82
    setup->frame_size = setup->width * setup->height * setup->bpp;
 
83
}
 
84
 
 
85
static void set_speed(setup_t *setup, size_t speed) {
51
86
    setup->fps = 1 + speed / setup->width / setup->height / setup->bpp;
52
87
}
53
88
 
54
 
void set_size(setup_t *setup, size_t size) {
 
89
static void set_size(setup_t *setup, size_t size) {
55
90
    setup->iters = size / setup->width / setup->height / setup->bpp;
56
91
}
57
92
 
58
 
void set_time(setup_t *setup, size_t time) {
 
93
static void set_time(setup_t *setup, size_t time) {
59
94
    setup->iters = time * setup->fps;
60
95
}
61
96
 
 
97
static int callback(setup_t *s, size_t result, void *buffer);
 
98
 
62
99
static void *run(setup_t *setup) {
 
100
#ifdef USE_UFO_GENERATOR
63
101
    GError *error = NULL;
64
102
    UfoGraph *graph = NULL;
65
103
    /* If you want to use system-wide installed filters: 
66
104
     * graph = ufo_graph_new(); */
67
105
 
68
106
    graph = g_object_new(UFO_TYPE_GRAPH,
69
 
#ifdef METABALLS_PATH
 
107
# ifdef METABALLS_PATH
70
108
            "paths", METABALLS_PATH,
71
 
#endif /* METABALLS_PATH */
 
109
# endif /* METABALLS_PATH */
72
110
            NULL);
73
111
 
74
112
//    printf("%lu %lu %lu %lu\n", setup->width, setup->height, setup->iters, setup->width * setup->height * setup->iters * sizeof(float));
92
130
    handle_error(error);
93
131
 
94
132
    setup->run_started = 1;
 
133
 
95
134
    ufo_graph_run(graph, &error);
96
135
    handle_error(error);
97
 
 
98
 
 
99
 
//    g_print("Wrote %lu bytes\n", width * height * num_iterations * sizeof(float));
 
136
#else /* USE_UFO_GENERATOR */
 
137
    size_t i;
 
138
    struct timeval tv;
 
139
    size_t size = setup->width * setup->height * setup->bpp;
 
140
    char buffer[size];
 
141
    double interval = 1000000. / setup->fps, nextus;
 
142
    ssize_t tmp;
 
143
    size_t nexts;
 
144
 
 
145
    setup->run_started = 1;
 
146
 
 
147
#ifdef USE_FIFO
 
148
    int fd = open(fifo_name, O_WRONLY);
 
149
    g_assert(fd >= 0);
 
150
#endif /* USE_FIFO */
 
151
 
 
152
    gettimeofday(&tv, NULL); 
 
153
    nexts = tv.tv_sec;
 
154
    nextus = tv.tv_usec + interval;
 
155
    for (i = 0; i < setup->iters; i++) {
 
156
#ifdef USE_FIFO
 
157
        ssize_t res = write(fd, buffer, size);
 
158
        g_assert(res == size);
 
159
#else /* USE_FIFO */
 
160
        callback(setup, size, buffer);
 
161
#endif /* USE_FIFO */
 
162
 
 
163
        tmp = ((size_t)round(nextus)) / 1000000;
 
164
        nexts += tmp;
 
165
        nextus -= tmp * 1000000;
 
166
 
 
167
        gettimeofday(&tv, NULL);
 
168
        tmp = (nexts - tv.tv_sec)*1000000 + (nextus - tv.tv_usec);
 
169
        if (tmp > 10) usleep(tmp);
 
170
        
 
171
        nextus += interval;
 
172
    }
 
173
 
 
174
#ifdef USE_FIFO
 
175
    close(fd);
 
176
#endif /* USE_FIFO */
 
177
 
 
178
#endif /* USE_UFO_GENERATOR */
100
179
 
101
180
    g_thread_exit(NULL);
102
181
    return NULL;
103
182
}
104
183
 
105
 
 
 
184
static int callback(setup_t *s, size_t result, void *buffer) {
 
185
    int err;
 
186
    struct timeval tv;
 
187
 
 
188
    fastwriter_t *fw = s->fw;
 
189
    fastwriter_stats_t stats;
 
190
 
 
191
    size_t duration, last_duration, expected;
 
192
    long delta;
 
193
 
 
194
 
 
195
    if (!s->broken_frame) {
 
196
        err = fastwriter_push(fw, result, buffer);
 
197
        if (err) {
 
198
            if (err == EWOULDBLOCK) {
 
199
                if (s->num_read) fastwriter_cancel(fw);
 
200
                s->broken_frame = 1;
 
201
            } else {
 
202
                if (err) printf("FastWriter returned error %i\n", err);
 
203
                g_assert(!err);
 
204
            }
 
205
        }
 
206
    }
 
207
 
 
208
    s->num_read += result; 
 
209
 
 
210
    if (s->num_read < s->frame_size) return 0;
 
211
 
 
212
    s->num_read = 0;
 
213
 
 
214
    if (s->broken_frame) {
 
215
        s->lost++;
 
216
        s->broken_frame = 0;
 
217
    } else {
 
218
        err = fastwriter_commit(fw);
 
219
        s->frames++;
 
220
    }
 
221
 
 
222
    gettimeofday(&tv, NULL);
 
223
    if (!s->tv_started.tv_sec) {
 
224
        memcpy(&s->tv_started, &tv, sizeof(struct timeval));
 
225
        if (s->tv_started.tv_usec >= (1000000 / s->fps)) 
 
226
            s->tv_started.tv_usec -= (1000000 / s->fps);
 
227
        else {
 
228
            s->tv_started.tv_sec--;
 
229
            s->tv_started.tv_usec += 1000000 - (1000000 / s->fps);
 
230
        }
 
231
        memcpy(&s->tv_last_written, &s->tv_started, sizeof(struct timeval));
 
232
    }
 
233
 
 
234
    fastwriter_get_stats(fw, &stats);
 
235
    if (stats.buffer_used > s->buf_max) s->buf_max = stats.buffer_used;
 
236
 
 
237
    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);
 
241
 
 
242
        if (((++s->writeouts)%WRITE_SUMMARY)==0) {
 
243
            duration = (tv.tv_sec - s->tv_started.tv_sec) * 1000000 + (tv.tv_usec - s->tv_started.tv_usec);
 
244
            expected = (tv.tv_sec - s->tv_started.tv_sec) * s->fps + round(1.*(tv.tv_usec - s->tv_started.tv_usec)*s->fps/1000000);
 
245
            delta = expected - s->lost - s->frames;
 
246
            if ((delta > DELTA_TOLERANCE)||(delta < -DELTA_TOLERANCE))
 
247
                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
                
 
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);
 
250
        }
 
251
        
 
252
        s->buf_max = 0;
 
253
        memcpy(&s->tv_last_written, &tv, sizeof(struct timeval));
 
254
        s->last_frames = s->frames;
 
255
        s->last_lost = s->lost;
 
256
    }
 
257
    
 
258
    return 0;
 
259
}
106
260
 
107
261
 
108
262
int main(int argc, char const* argv[])
109
263
{
110
264
    int err;
 
265
 
 
266
#ifdef USE_FIFO
111
267
    GError *gerr;
112
268
    GThread *thr;
 
269
#endif /* USE_FIFO */
 
270
 
113
271
    setup_t setup;
114
 
    fastwriter_t *fw;
115
 
    fastwriter_stats_t stats;
116
272
    const char *out = "/dev/null";
 
273
    size_t width = 1024;
 
274
    size_t height = 768;
117
275
    size_t speed = 850;
118
276
 
119
 
    size_t num_read = 0;
120
 
    size_t buf_max = 0;
121
 
    
122
 
    int broken_frame = 0;
123
 
    size_t writeouts = 0;
124
 
    size_t duration, last_duration;
125
 
    struct timeval tv;
126
 
    struct timeval tv_started = {0};
127
 
    struct timeval tv_last_written = {0};
128
 
    unsigned long frames = 0, lost = 0;
129
 
    unsigned long delta, expected;
130
 
    unsigned long last_frames = 0, last_lost = 0;
131
 
    
132
 
 
133
 
    g_thread_init(NULL);    
 
277
    fastwriter_t *fw;
 
278
    fastwriter_stats_t stats;
 
279
 
 
280
    g_thread_init(NULL);
 
281
 
 
282
#ifdef USE_UFO_GENERATOR
134
283
    g_type_init();
 
284
#endif /* USE_UFO_GENERATOR */
135
285
 
136
286
    if (argc > 1) {
137
287
        out = argv[1];
141
291
        speed = atoi(argv[2]);
142
292
    }
143
293
 
 
294
#ifdef USE_FIFO
144
295
    unlink(fifo_name);
145
296
    g_assert(!mkfifo(fifo_name, S_IWUSR | S_IRUSR));
 
297
#endif /* USE_FIFO */
146
298
 
147
299
    fw = fastwriter_init(out, FASTWRITER_FLAGS_OVERWRITE);
148
300
    g_assert(fw);
149
301
    
150
302
    err = fastwriter_open(fw, out,  FASTWRITER_FLAGS_OVERWRITE);
151
303
    if (err) printf("FastWriter returned error %i\n", err);
152
 
 
153
304
    g_assert(!err);
154
305
 
155
306
    fastwriter_set_buffer_size(fw, FW_BUFFER * 1024 * 1024);
156
307
    
157
308
    fastwriter_get_stats(fw, &stats);
158
 
    printf("*** Writing to %s, speed: %lu MB/s, buffer: %lu MB\n", out, speed, stats.buffer_size);
159
309
 
160
310
    memset(&setup, 0, sizeof(setup_t));
 
311
 
 
312
    setup.fw = fw;
 
313
    set_dim(&setup, width, height);
161
314
    set_speed(&setup, speed * 1024 * 1024);
162
315
    set_size(&setup, run_time * speed * 1024 * 1024);
163
316
 
164
 
    size_t frame_size = setup.width * setup.height * setup.bpp;
165
 
    void *buffer = malloc(frame_size);
 
317
    printf("*** Writing to %s, rate: %lu, data: %lu MB/s, buffer: %lu MB\n", out, setup.fps, speed, stats.buffer_size);
 
318
 
 
319
    void *buffer = malloc(setup.frame_size);
166
320
    g_assert(buffer);
167
321
 
 
322
#ifdef USE_FIFO
168
323
    thr = g_thread_create((GThreadFunc)run, &setup, 1, &gerr);
169
324
    g_assert(thr);
170
325
 
173
328
    int fd = open(fifo_name, O_RDONLY);
174
329
    g_assert(fd);
175
330
 
176
 
    ssize_t result = read(fd, buffer, frame_size);
 
331
    ssize_t result = read(fd, buffer, setup.frame_size);
177
332
 
178
333
    while (result > 0) {
179
 
        if (!broken_frame) {
180
 
            err = fastwriter_push(fw, result, buffer);
181
 
            if (err) {
182
 
                if (err == EWOULDBLOCK) {
183
 
                    if (num_read) fastwriter_cancel(fw);
184
 
                    broken_frame = 1;
185
 
                } else {
186
 
                    if (err) printf("FastWriter returned error %i\n", err);
187
 
                    g_assert(!err);
188
 
                }
189
 
            }
190
 
        }
191
 
        
192
 
        num_read += result; 
193
 
        
194
 
        if (num_read < frame_size) {
195
 
            result = read(fd, buffer, frame_size - num_read);
196
 
            continue;
197
 
        }
198
 
 
199
 
        gettimeofday(&tv, NULL);
200
 
        if (!tv_started.tv_sec) {
201
 
            memcpy(&tv_started, &tv, sizeof(struct timeval));
202
 
            if (tv_started.tv_usec >= (1000000 / setup.fps)) 
203
 
                tv_started.tv_usec -= (1000000 / setup.fps);
204
 
            else {
205
 
                tv_started.tv_sec--;
206
 
                tv_started.tv_usec += 1000000 - (1000000 / setup.fps);
207
 
            }
208
 
            memcpy(&tv_last_written, &tv_started, sizeof(struct timeval));
209
 
        }
210
 
    
211
 
        num_read = 0;
212
 
 
213
 
        if (broken_frame) {
214
 
            lost++;
215
 
        } else {
216
 
            err = fastwriter_commit(fw);
217
 
            frames++;
218
 
        }
219
 
 
220
 
        fastwriter_get_stats(fw, &stats);
221
 
        if (stats.buffer_used > buf_max) buf_max = stats.buffer_used;
222
 
 
223
 
        if ((tv.tv_sec - tv_last_written.tv_sec) >= WRITE_INTERVAL) {
224
 
            last_duration = (tv.tv_sec - tv_last_written.tv_sec) * 1000000 + (tv.tv_usec - tv_last_written.tv_usec);
225
 
 
226
 
/*          expected = (tv.tv_sec - tv_last_summary.tv_sec) * setup.fps + (tv.tv_usec - tv_last_summary.tv_usec) * setup.fps / 1000000;
227
 
            delta = expected - lost - frames;
228
 
            if (delta > 0) delta--;*/
229
 
 
230
 
            printf("Lost  %6.2lf%% (% 8lu of % 8lu), %9.3lf GB at %8.3lf MB/s, buf:%6.2lf%%\n", 100.*(lost - last_lost) / (lost + frames - last_lost - last_frames), lost - last_lost, lost + frames - (last_lost + last_frames), 1. * frame_size * (frames - last_frames) / 1024 / 1024 / 1024, 1000000. * frame_size * (frames - last_frames) / last_duration / 1024 / 1024, 100.*buf_max/stats.buffer_size);
231
 
 
232
 
            if (((++writeouts)%WRITE_SUMMARY)==0) {
233
 
                duration = (tv.tv_sec - tv_started.tv_sec) * 1000000 + (tv.tv_usec - tv_started.tv_usec);
234
 
                
235
 
                expected = (tv.tv_sec - tv_started.tv_sec) * setup.fps + round(1.*(tv.tv_usec - tv_started.tv_usec)*setup.fps/1000000);
236
 
                    
237
 
                delta = expected - lost - frames;
238
 
                if ((delta > 1)||(delta < 1))
239
 
                    printf(" *** Unexpected frame rate: %.2lf (%lu), delta: %li (%lu, %lu)\n", 1000000. * (frames + lost) / duration, setup.fps, delta, lost + frames, expected); 
240
 
                
241
 
                printf("Total %6.2lf%% (% 8lu of % 8lu), %9.3lf GB at %8.3lf MB/s, buf:%6.2lf%%\n", 100.*lost / (lost + frames), lost, lost + frames, 1. * frames * frame_size / 1024 / 1024 / 1024, 1000000. * frames * frame_size / duration / 1024 / 1024,  100.*stats.buffer_max / stats.buffer_size);
242
 
            }
243
 
        
244
 
            buf_max = 0;
245
 
            memcpy(&tv_last_written, &tv, sizeof(struct timeval));
246
 
            last_frames = frames;
247
 
            last_lost = lost;
248
 
        }
249
 
        
250
 
        result = read(fd, buffer, frame_size);
 
334
        callback(&setup, result, buffer);
 
335
        result = read(fd, buffer, setup.frame_size - setup.num_read);
251
336
    }
252
337
 
253
 
    printf("Wrote %lu GB\n", frame_size * frames / 1024 / 1024 / 1024);
 
338
    printf("Wrote %lu GB\n", setup.frame_size * setup.frames / 1024 / 1024 / 1024);
254
339
 
255
340
    g_thread_join(thr);
256
341
 
257
342
    close(fd);
 
343
#else /* USE_FIFO */
 
344
    run(&setup);
 
345
#endif /* USE_FIFO */
258
346
 
259
347
    free(buffer);
260
348
    fastwriter_close(fw);
261
349
    fastwriter_destroy(fw);
 
350
 
 
351
#ifdef USE_FIFO
262
352
    unlink(fifo_name);
 
353
#endif /* USE_FIFO */
263
354
 
264
355
    return 0;
265
356
}