]>
Commit | Line | Data |
---|---|---|
ed486911 | 1 | /* |
f7deaa1a | 2 | * "$Id: rasterbench.c 5667 2006-06-16 10:21:49Z mike $" |
ed486911 | 3 | * |
4 | * Raster benchmark program for the Common UNIX Printing System (CUPS). | |
5 | * | |
6 | * Copyright 1997-2006 by Easy Software Products. | |
7 | * | |
8 | * These coded instructions, statements, and computer programs are the | |
9 | * property of Easy Software Products and are protected by Federal | |
10 | * copyright law. Distribution and use rights for the CUPS Raster source | |
11 | * files are outlined in the GNU Library General Public License, located | |
12 | * in the "pstoraster" directory. If this file is missing or damaged | |
13 | * please contact Easy Software Products at: | |
14 | * | |
15 | * Attn: CUPS Licensing Information | |
16 | * Easy Software Products | |
17 | * 44141 Airport View Drive, Suite 204 | |
18 | * Hollywood, Maryland 20636 USA | |
19 | * | |
20 | * Voice: (301) 373-9600 | |
21 | * EMail: cups-info@cups.org | |
22 | * WWW: http://www.cups.org | |
23 | * | |
24 | * This code and any derivative of it may be used and distributed | |
25 | * freely under the terms of the GNU General Public License when | |
26 | * used with GNU Ghostscript or its derivatives. Use of the code | |
27 | * (or any derivative of it) with software other than GNU | |
28 | * GhostScript (or its derivatives) is governed by the CUPS license | |
29 | * agreement. | |
30 | * | |
31 | * This file is subject to the Apple OS-Developed Software exception. | |
32 | * | |
33 | * Contents: | |
34 | * | |
35 | * main() - Benchmark the raster read/write functions. | |
36 | * compute_median() - Compute the median time for a test. | |
37 | * read_test() - Benchmark the raster read functions. | |
38 | * write_test() - Benchmark the raster write functions. | |
39 | */ | |
40 | ||
41 | /* | |
42 | * Include necessary headers... | |
43 | */ | |
44 | ||
45 | #include "raster.h" | |
46 | #include <stdlib.h> | |
47 | #include <sys/time.h> | |
48 | #include <signal.h> | |
49 | #include <unistd.h> | |
50 | #include <sys/wait.h> | |
51 | ||
52 | ||
53 | /* | |
54 | * Constants... | |
55 | */ | |
56 | ||
57 | #define TEST_WIDTH 1024 | |
58 | #define TEST_HEIGHT 1024 | |
59 | #define TEST_PAGES 16 | |
60 | #define TEST_PASSES 20 | |
61 | ||
62 | ||
63 | /* | |
64 | * Local functions... | |
65 | */ | |
66 | ||
67 | static double compute_median(double *secs); | |
68 | static double get_time(void); | |
69 | static void read_test(int fd); | |
70 | static int run_read_test(void); | |
71 | static void write_test(int fd); | |
72 | ||
73 | ||
74 | /* | |
75 | * 'main()' - Benchmark the raster read/write functions. | |
76 | */ | |
77 | ||
78 | int /* O - Exit status */ | |
79 | main(void) | |
80 | { | |
81 | int i; /* Looping var */ | |
82 | int ras_fd, /* File descriptor for read process */ | |
83 | status; /* Exit status of read process */ | |
84 | double start_secs, /* Start time */ | |
85 | write_secs, /* Write time */ | |
86 | read_secs, /* Read time */ | |
87 | pass_secs[TEST_PASSES]; /* Total test times */ | |
88 | ||
89 | ||
90 | /* | |
91 | * Ignore SIGPIPE... | |
92 | */ | |
93 | ||
94 | signal(SIGPIPE, SIG_IGN); | |
95 | ||
96 | /* | |
97 | * Run the tests several times to get a good average... | |
98 | */ | |
99 | ||
100 | printf("Test read/write speed of %d pages, %dx%d pixels...\n\n", | |
101 | TEST_PAGES, TEST_WIDTH, TEST_HEIGHT); | |
102 | for (i = 0; i < TEST_PASSES; i ++) | |
103 | { | |
104 | printf("PASS %2d: ", i + 1); | |
105 | fflush(stdout); | |
106 | ||
107 | ras_fd = run_read_test(); | |
108 | start_secs = get_time(); | |
109 | ||
110 | write_test(ras_fd); | |
111 | ||
112 | write_secs = get_time(); | |
113 | printf(" %.3f write,", write_secs - start_secs); | |
114 | fflush(stdout); | |
115 | ||
116 | close(ras_fd); | |
117 | wait(&status); | |
118 | ||
119 | read_secs = get_time(); | |
120 | pass_secs[i] = read_secs - start_secs; | |
121 | printf(" %.3f read, %.3f total\n", read_secs - write_secs, pass_secs[i]); | |
122 | } | |
123 | ||
124 | printf("\nMedian Total Time: %.3f seconds per document\n", | |
125 | compute_median(pass_secs)); | |
126 | ||
127 | return (0); | |
128 | } | |
129 | ||
130 | ||
131 | /* | |
132 | * 'compute_median()' - Compute the median time for a test. | |
133 | */ | |
134 | ||
135 | static double /* O - Median time in seconds */ | |
136 | compute_median(double *secs) /* I - Array of time samples */ | |
137 | { | |
138 | int i, j; /* Looping vars */ | |
139 | double temp; /* Swap variable */ | |
140 | ||
141 | ||
142 | /* | |
143 | * Sort the array into ascending order using a quicky bubble sort... | |
144 | */ | |
145 | ||
146 | for (i = 0; i < (TEST_PASSES - 1); i ++) | |
147 | for (j = i + 1; j < TEST_PASSES; j ++) | |
148 | if (secs[i] > secs[j]) | |
149 | { | |
150 | temp = secs[i]; | |
151 | secs[i] = secs[j]; | |
152 | secs[j] = temp; | |
153 | } | |
154 | ||
155 | /* | |
156 | * Return the average of the middle two samples... | |
157 | */ | |
158 | ||
159 | return (0.5 * (secs[TEST_PASSES / 2 - 1] + secs[TEST_PASSES / 2])); | |
160 | } | |
161 | ||
162 | ||
163 | /* | |
164 | * 'get_time()' - Get the current time in seconds. | |
165 | */ | |
166 | ||
167 | static double /* O - Time in seconds */ | |
168 | get_time(void) | |
169 | { | |
170 | struct timeval curtime; /* Current time */ | |
171 | ||
172 | ||
173 | gettimeofday(&curtime, NULL); | |
174 | return (curtime.tv_sec + 0.000001 * curtime.tv_usec); | |
175 | } | |
176 | ||
177 | ||
178 | /* | |
179 | * 'read_test()' - Benchmark the raster read functions. | |
180 | */ | |
181 | ||
182 | static void | |
183 | read_test(int fd) /* I - File descriptor to read from */ | |
184 | { | |
185 | int y; /* Looping var */ | |
186 | cups_raster_t *r; /* Raster stream */ | |
187 | cups_page_header_t header; /* Page header */ | |
188 | unsigned char buffer[8 * TEST_WIDTH]; | |
189 | /* Read buffer */ | |
190 | ||
191 | ||
192 | /* | |
193 | * Test read speed... | |
194 | */ | |
195 | ||
196 | if ((r = cupsRasterOpen(fd, CUPS_RASTER_READ)) == NULL) | |
197 | { | |
198 | perror("Unable to create raster input stream"); | |
199 | return; | |
200 | } | |
201 | ||
202 | while (cupsRasterReadHeader(r, &header)) | |
203 | { | |
204 | for (y = 0; y < header.cupsHeight; y ++) | |
205 | cupsRasterReadPixels(r, buffer, header.cupsBytesPerLine); | |
206 | } | |
207 | ||
208 | cupsRasterClose(r); | |
209 | } | |
210 | ||
211 | ||
212 | /* | |
213 | * 'run_read_test()' - Run the read test as a child process via pipes. | |
214 | */ | |
215 | ||
216 | static int /* O - Standard input of child */ | |
217 | run_read_test(void) | |
218 | { | |
219 | int ras_pipes[2]; /* Raster data pipes */ | |
220 | int pid; /* Child process ID */ | |
221 | ||
222 | ||
223 | if (pipe(ras_pipes)) | |
224 | return (-1); | |
225 | ||
226 | if ((pid = fork()) < 0) | |
227 | { | |
228 | /* | |
229 | * Fork error - return -1 on error... | |
230 | */ | |
231 | ||
232 | close(ras_pipes[0]); | |
233 | close(ras_pipes[1]); | |
234 | ||
235 | return (-1); | |
236 | } | |
237 | else if (pid == 0) | |
238 | { | |
239 | /* | |
240 | * Child comes here - read data from the input pipe... | |
241 | */ | |
242 | ||
243 | close(ras_pipes[1]); | |
244 | read_test(ras_pipes[0]); | |
245 | exit(0); | |
246 | } | |
247 | else | |
248 | { | |
249 | /* | |
250 | * Parent comes here - return the output pipe... | |
251 | */ | |
252 | ||
253 | close(ras_pipes[0]); | |
254 | return (ras_pipes[1]); | |
255 | } | |
256 | } | |
257 | ||
258 | ||
259 | /* | |
260 | * 'write_test()' - Benchmark the raster write functions. | |
261 | */ | |
262 | ||
263 | static void | |
264 | write_test(int fd) /* I - File descriptor to write to */ | |
265 | { | |
266 | int page, x, y; /* Looping vars */ | |
267 | int count; /* Number of bytes to set */ | |
268 | cups_raster_t *r; /* Raster stream */ | |
269 | cups_page_header_t header; /* Page header */ | |
270 | unsigned char data[32][8 * TEST_WIDTH]; | |
271 | /* Raster data to write */ | |
272 | ||
273 | ||
274 | /* | |
275 | * Create a combination of random data and repeated data to simulate | |
276 | * text with some whitespace. | |
277 | */ | |
278 | ||
279 | srand(time(NULL)); | |
280 | ||
281 | memset(data, 0, sizeof(data)); | |
282 | ||
283 | for (y = 0; y < 28; y ++) | |
284 | { | |
285 | for (x = rand() & 127, count = (rand() & 15) + 1; | |
286 | x < sizeof(data[0]); | |
287 | x ++, count --) | |
288 | { | |
289 | if (count <= 0) | |
290 | { | |
291 | x += (rand() & 15) + 1; | |
292 | count = (rand() & 15) + 1; | |
293 | ||
294 | if (x >= sizeof(data[0])) | |
295 | break; | |
296 | } | |
297 | ||
298 | data[y][x] = rand(); | |
299 | } | |
300 | } | |
301 | ||
302 | /* | |
303 | * Test write speed... | |
304 | */ | |
305 | ||
306 | if ((r = cupsRasterOpen(fd, CUPS_RASTER_WRITE)) == NULL) | |
307 | { | |
308 | perror("Unable to create raster output stream"); | |
309 | return; | |
310 | } | |
311 | ||
312 | for (page = 0; page < TEST_PAGES; page ++) | |
313 | { | |
314 | memset(&header, 0, sizeof(header)); | |
315 | header.cupsWidth = TEST_WIDTH; | |
316 | header.cupsHeight = TEST_HEIGHT; | |
317 | header.cupsBytesPerLine = TEST_WIDTH; | |
318 | ||
319 | if (page & 1) | |
320 | { | |
321 | header.cupsBytesPerLine *= 4; | |
322 | header.cupsColorSpace = CUPS_CSPACE_CMYK; | |
323 | header.cupsColorOrder = CUPS_ORDER_CHUNKED; | |
324 | } | |
325 | else | |
326 | { | |
327 | header.cupsColorSpace = CUPS_CSPACE_K; | |
328 | header.cupsColorOrder = CUPS_ORDER_BANDED; | |
329 | } | |
330 | ||
331 | if (page & 2) | |
332 | { | |
333 | header.cupsBytesPerLine *= 2; | |
334 | header.cupsBitsPerColor = 16; | |
335 | header.cupsBitsPerPixel = (page & 1) ? 64 : 16; | |
336 | } | |
337 | else | |
338 | { | |
339 | header.cupsBitsPerColor = 8; | |
340 | header.cupsBitsPerPixel = (page & 1) ? 32 : 8; | |
341 | } | |
342 | ||
343 | cupsRasterWriteHeader(r, &header); | |
344 | ||
345 | for (y = 0; y < TEST_HEIGHT; y ++) | |
346 | cupsRasterWritePixels(r, data[y & 31], header.cupsBytesPerLine); | |
347 | } | |
348 | ||
349 | cupsRasterClose(r); | |
350 | } | |
351 | ||
352 | ||
353 | /* | |
f7deaa1a | 354 | * End of "$Id: rasterbench.c 5667 2006-06-16 10:21:49Z mike $". |
ed486911 | 355 | */ |