bzr branch
http://darksoft.org/webbzr/alps/fwbench
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
1 |
#define _BSD_SOURCE
|
1
by Suren A. Chilingaryan
Initial release |
2 |
#include <stdio.h> |
3 |
#include <stdlib.h> |
|
4 |
#include <string.h> |
|
5 |
#include <errno.h> |
|
6 |
#include <fcntl.h> |
|
7 |
#include <glib.h> |
|
8 |
#include <math.h> |
|
9 |
#include <unistd.h> |
|
10 |
#include <sys/stat.h> |
|
11 |
#include <sys/time.h> |
|
12 |
||
13 |
#include <fastwriter.h> |
|
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
14 |
|
15 |
#ifdef USE_UFO_GENERATOR
|
|
16 |
# include <ufo/ufo-graph.h>
|
|
17 |
#endif /* USE_UFO_GENERATOR */ |
|
1
by Suren A. Chilingaryan
Initial release |
18 |
|
19 |
#include "config.h" |
|
20 |
||
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
21 |
//#define USE_FIFO
|
1
by Suren A. Chilingaryan
Initial release |
22 |
#define FW_BUFFER 4096l
|
23 |
#define WRITE_INTERVAL 1
|
|
24 |
#define WRITE_SUMMARY 5
|
|
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
25 |
#define DELTA_TOLERANCE 5
|
1
by Suren A. Chilingaryan
Initial release |
26 |
#define NEWFILE 10
|
27 |
||
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
28 |
#ifdef USE_UFO_GENERATOR
|
29 |
# ifndef USE_FIFO
|
|
30 |
# define USE_FIFO
|
|
31 |
# endif /* !USE_FIFO */ |
|
32 |
#endif /* USE_UFO_GENERATOR */ |
|
1
by Suren A. Chilingaryan
Initial release |
33 |
|
34 |
#define run_time 3600
|
|
35 |
const char *fifo_name = ".fifo"; |
|
36 |
||
37 |
struct setup_s { |
|
38 |
size_t width; |
|
39 |
size_t height; |
|
40 |
size_t bpp; |
|
41 |
size_t fps; |
|
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
42 |
|
1
by Suren A. Chilingaryan
Initial release |
43 |
size_t iters; |
44 |
||
45 |
volatile int run_started; |
|
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
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; |
|
1
by Suren A. Chilingaryan
Initial release |
61 |
};
|
62 |
||
63 |
typedef struct setup_s setup_t; |
|
64 |
||
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
65 |
|
66 |
#ifdef USE_UFO_GENERATOR
|
|
67 |
static void handle_error(GError *error) { |
|
1
by Suren A. Chilingaryan
Initial release |
68 |
if (error != NULL) { |
69 |
g_print("%s\n", error->message); |
|
70 |
g_error_free(error); |
|
71 |
exit(EXIT_FAILURE); |
|
72 |
}
|
|
73 |
}
|
|
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
74 |
#endif /* USE_UFO_GENERATOR */ |
75 |
||
76 |
||
77 |
static void set_dim(setup_t *setup, size_t width, size_t height) { |
|
1
by Suren A. Chilingaryan
Initial release |
78 |
setup->bpp = sizeof(float); |
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
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) { |
|
1
by Suren A. Chilingaryan
Initial release |
86 |
setup->fps = 1 + speed / setup->width / setup->height / setup->bpp; |
87 |
}
|
|
88 |
||
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
89 |
static void set_size(setup_t *setup, size_t size) { |
1
by Suren A. Chilingaryan
Initial release |
90 |
setup->iters = size / setup->width / setup->height / setup->bpp; |
91 |
}
|
|
92 |
||
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
93 |
static void set_time(setup_t *setup, size_t time) { |
1
by Suren A. Chilingaryan
Initial release |
94 |
setup->iters = time * setup->fps; |
95 |
}
|
|
96 |
||
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
97 |
static int callback(setup_t *s, size_t result, void *buffer); |
98 |
||
1
by Suren A. Chilingaryan
Initial release |
99 |
static void *run(setup_t *setup) { |
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
100 |
#ifdef USE_UFO_GENERATOR
|
1
by Suren A. Chilingaryan
Initial release |
101 |
GError *error = NULL; |
102 |
UfoGraph *graph = NULL; |
|
103 |
/* If you want to use system-wide installed filters:
|
|
104 |
* graph = ufo_graph_new(); */
|
|
105 |
||
106 |
graph = g_object_new(UFO_TYPE_GRAPH, |
|
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
107 |
# ifdef METABALLS_PATH
|
1
by Suren A. Chilingaryan
Initial release |
108 |
"paths", METABALLS_PATH, |
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
109 |
# endif /* METABALLS_PATH */ |
1
by Suren A. Chilingaryan
Initial release |
110 |
NULL); |
111 |
||
112 |
// printf("%lu %lu %lu %lu\n", setup->width, setup->height, setup->iters, setup->width * setup->height * setup->iters * sizeof(float));
|
|
113 |
UfoFilter *metaballs = ufo_graph_get_filter(graph, "metaballs", &error); |
|
114 |
handle_error(error); |
|
115 |
g_object_set(G_OBJECT(metaballs), |
|
116 |
"width", setup->width, |
|
117 |
"height", setup->height, |
|
118 |
"num-balls", 1, |
|
119 |
"num-iterations", setup->iters, |
|
120 |
"frames-per-second", setup->fps, |
|
121 |
NULL); |
|
122 |
||
123 |
UfoFilter *writer = ufo_graph_get_filter(graph, "pipeoutput", &error); |
|
124 |
handle_error(error); |
|
125 |
g_object_set(G_OBJECT(writer), |
|
126 |
"pipe-name", fifo_name, |
|
127 |
NULL); |
|
128 |
||
129 |
ufo_filter_connect_to(metaballs, writer, &error); |
|
130 |
handle_error(error); |
|
131 |
||
132 |
setup->run_started = 1; |
|
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
133 |
|
1
by Suren A. Chilingaryan
Initial release |
134 |
ufo_graph_run(graph, &error); |
135 |
handle_error(error); |
|
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
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 */ |
|
1
by Suren A. Chilingaryan
Initial release |
179 |
|
180 |
g_thread_exit(NULL); |
|
181 |
return NULL; |
|
182 |
}
|
|
183 |
||
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
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 |
}
|
|
1
by Suren A. Chilingaryan
Initial release |
260 |
|
261 |
||
262 |
int main(int argc, char const* argv[]) |
|
263 |
{
|
|
264 |
int err; |
|
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
265 |
|
266 |
#ifdef USE_FIFO
|
|
1
by Suren A. Chilingaryan
Initial release |
267 |
GError *gerr; |
268 |
GThread *thr; |
|
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
269 |
#endif /* USE_FIFO */ |
270 |
||
1
by Suren A. Chilingaryan
Initial release |
271 |
setup_t setup; |
272 |
const char *out = "/dev/null"; |
|
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
273 |
size_t width = 1024; |
274 |
size_t height = 768; |
|
1
by Suren A. Chilingaryan
Initial release |
275 |
size_t speed = 850; |
276 |
||
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
277 |
fastwriter_t *fw; |
278 |
fastwriter_stats_t stats; |
|
279 |
||
280 |
g_thread_init(NULL); |
|
281 |
||
282 |
#ifdef USE_UFO_GENERATOR
|
|
1
by Suren A. Chilingaryan
Initial release |
283 |
g_type_init(); |
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
284 |
#endif /* USE_UFO_GENERATOR */ |
1
by Suren A. Chilingaryan
Initial release |
285 |
|
286 |
if (argc > 1) { |
|
287 |
out = argv[1]; |
|
288 |
}
|
|
289 |
||
290 |
if (argc > 2) { |
|
291 |
speed = atoi(argv[2]); |
|
292 |
}
|
|
293 |
||
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
294 |
#ifdef USE_FIFO
|
1
by Suren A. Chilingaryan
Initial release |
295 |
unlink(fifo_name); |
296 |
g_assert(!mkfifo(fifo_name, S_IWUSR | S_IRUSR)); |
|
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
297 |
#endif /* USE_FIFO */ |
1
by Suren A. Chilingaryan
Initial release |
298 |
|
299 |
fw = fastwriter_init(out, FASTWRITER_FLAGS_OVERWRITE); |
|
300 |
g_assert(fw); |
|
301 |
||
302 |
err = fastwriter_open(fw, out, FASTWRITER_FLAGS_OVERWRITE); |
|
303 |
if (err) printf("FastWriter returned error %i\n", err); |
|
304 |
g_assert(!err); |
|
305 |
||
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)); |
|
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
311 |
|
312 |
setup.fw = fw; |
|
313 |
set_dim(&setup, width, height); |
|
1
by Suren A. Chilingaryan
Initial release |
314 |
set_speed(&setup, speed * 1024 * 1024); |
315 |
set_size(&setup, run_time * speed * 1024 * 1024); |
|
316 |
||
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
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); |
|
1
by Suren A. Chilingaryan
Initial release |
320 |
g_assert(buffer); |
321 |
||
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
322 |
#ifdef USE_FIFO
|
1
by Suren A. Chilingaryan
Initial release |
323 |
thr = g_thread_create((GThreadFunc)run, &setup, 1, &gerr); |
324 |
g_assert(thr); |
|
325 |
||
326 |
while (!setup.run_started); |
|
327 |
||
328 |
int fd = open(fifo_name, O_RDONLY); |
|
329 |
g_assert(fd); |
|
330 |
||
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
331 |
ssize_t result = read(fd, buffer, setup.frame_size); |
1
by Suren A. Chilingaryan
Initial release |
332 |
|
333 |
while (result > 0) { |
|
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
334 |
callback(&setup, result, buffer); |
335 |
result = read(fd, buffer, setup.frame_size - setup.num_read); |
|
1
by Suren A. Chilingaryan
Initial release |
336 |
}
|
337 |
||
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
338 |
printf("Wrote %lu GB\n", setup.frame_size * setup.frames / 1024 / 1024 / 1024); |
1
by Suren A. Chilingaryan
Initial release |
339 |
|
340 |
g_thread_join(thr); |
|
341 |
||
342 |
close(fd); |
|
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
343 |
#else /* USE_FIFO */ |
344 |
run(&setup); |
|
345 |
#endif /* USE_FIFO */ |
|
1
by Suren A. Chilingaryan
Initial release |
346 |
|
347 |
free(buffer); |
|
348 |
fastwriter_close(fw); |
|
349 |
fastwriter_destroy(fw); |
|
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
350 |
|
351 |
#ifdef USE_FIFO
|
|
1
by Suren A. Chilingaryan
Initial release |
352 |
unlink(fifo_name); |
2
by Suren A. Chilingaryan
Use local data generator until high-speed ufo simulator is provided |
353 |
#endif /* USE_FIFO */ |
1
by Suren A. Chilingaryan
Initial release |
354 |
|
355 |
return 0; |
|
356 |
}
|