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