diff options
Diffstat (limited to 'gs/base/bench.c')
-rw-r--r-- | gs/base/bench.c | 435 |
1 files changed, 435 insertions, 0 deletions
diff --git a/gs/base/bench.c b/gs/base/bench.c new file mode 100644 index 000000000..c1d7b8d75 --- /dev/null +++ b/gs/base/bench.c @@ -0,0 +1,435 @@ +/* Copyright (C) 2001-2006 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, modified + or distributed except as expressly authorized under the terms of that + license. Refer to licensing information at http://www.artifex.com/ + or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, + San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information. +*/ + +/* $Id$ */ +/* Simple hardware benchmarking suite (C and PostScript) */ +#include "stdio_.h" +#include <stdlib.h> + +/* Patchup for GS externals */ +FILE *gs_stdout; +FILE *gs_stderr; +FILE *gs_debug_out; +const char gp_scratch_file_name_prefix[] = "gs_"; +static void +capture_stdio(void) +{ + gs_stdout = stdout; + gs_stderr = stderr; + gs_debug_out = stderr; +} +#include "gsio.h" +#undef gs_stdout +#undef gs_stderr +#undef stdout +#define stdout gs_stdout +#undef stderr +#define stderr gs_stderr +FILE * +gp_open_scratch_file(const char *prefix, char *fname, const char *mode) +{ + return NULL; +} +void +gp_set_printer_binary(int prnfno, int binary) +{ +} +void +gs_to_exit(int n) +{ +} +#define eprintf_program_ident(f, pn, rn) (void)0 +void +lprintf_file_and_line(FILE * f, const char *file, int line) +{ + fprintf(f, "%s(%d): ", file, line); +} + +/* + * Read the CPU time (in seconds since an implementation-defined epoch) + * into ptm[0], and fraction (in nanoseconds) into ptm[1]. + */ +#include "gp_unix.c" +#undef stdout +#define stdout gs_stdout +#undef stderr +#define stderr gs_stderr + +/* Loop unrolling macros */ +#define do10(x) x;x;x;x;x; x;x;x;x;x + +/* Define the actual benchmarks. */ +static int +iadd(int a, int n, char **msg) +{ + int b = 0, i; + + for (i = n / 20; --i >= 0;) { + do10((b += a, b += i)); + } + *msg = "integer adds"; + return b; +} +static int +imul(int a, int n, char **msg) +{ + int b = 1, i; + + for (i = n / 20; --i > 0;) { + do10((b *= a, b *= i)); + } + *msg = "integer multiplies"; + return b; +} +static int +idiv(int a, int n, char **msg) +{ + int b = 1, i; + + for (i = n / 20; --i > 0;) { + b += 999999; + do10((b /= a, b /= i)); + } + *msg = "integer divides"; + return b; +} +static int +fadd(float a, int n, char **msg) +{ + float b = 0; + int i; + + for (i = n / 10; --i >= 0;) { + do10((b += a)); + } + *msg = "floating adds"; + return b; +} +static int +fmul(float a, int n, char **msg) +{ + float b = 1; + int i; + + for (i = n / 10; --i >= 0;) { + do10((b *= a)); + } + *msg = "floating multiplies"; + return b; +} +static int +fdiv(float a, int n, char **msg) +{ + float b = 1; + int i; + + for (i = n / 10; --i >= 0;) { + do10((b /= a)); + } + *msg = "floating divides"; + return b; +} +static int +fconv(int a, int n, char **msg) +{ + int b[10]; + float f[10]; + int i; + + b[0] = a; + for (i = n / 20; --i >= 0;) + f[0] = b[0], f[1] = b[1], f[2] = b[2], f[3] = b[3], f[4] = b[4], + f[5] = b[5], f[6] = b[6], f[7] = b[7], f[8] = b[8], f[9] = b[9], + b[0] = f[1], b[1] = f[2], b[2] = f[3], b[3] = f[4], b[4] = f[5], + b[5] = f[6], b[6] = f[7], b[7] = f[8], b[8] = f[9], b[9] = f[0]; + *msg = "float/int conversions"; + return b[0]; +} +static int +mfast(int *m, int n, char **msg) +{ + int i; + + m[0] = n; + for (i = n / 20; --i >= 0;) + m[9] = m[8], m[8] = m[7], m[7] = m[6], m[6] = m[5], m[5] = m[4], + m[4] = m[3], m[3] = m[2], m[2] = m[1], m[1] = m[0], m[0] = m[9]; + *msg = "fast memory accesses"; + return m[0]; +} +static int +mslow(int *m, int n, char **msg) +{ + int *p; + int i, k = 0; + + m[0] = n; + for (i = n / 20; --i >= 0; k = (k + 397) & 0x3ffff) + p = m + k, + p[0] = p[100], p[20] = p[120], p[40] = p[140], + p[60] = p[160], p[80] = p[180], + p[200] = p[300], p[220] = p[320], p[240] = p[340], + p[260] = p[360], p[280] = p[380]; + *msg = "slow memory accesses"; + return m[0]; +} + +int +main(int argc, const char *argv[]) +{ + int i; + int *mem = malloc(1100000); + + capture_stdio(); + for (i = 0;; ++i) { + long t0[2], t1[2]; + char *msg; + int n; + + gp_get_usertime(t0); + switch (i) { + case 0: + iadd(0, n = 10000000, &msg); + break; + case 1: + imul(1, n = 1000000, &msg); + break; + case 2: + idiv(1, n = 1000000, &msg); + break; + case 3: + fadd(3.14, n = 10000000, &msg); + break; + case 4: + fmul(1.0000001, n = 10000000, &msg); + break; + case 5: + fdiv(1.0000001, n = 1000000, &msg); + break; + case 6: + fconv(12345, n = 10000000, &msg); + break; + case 7: + mfast(mem, n = 10000000, &msg); + break; + case 8: + mslow(mem, n = 1000000, &msg); + break; + default: + free(mem); + exit(0); + } + gp_get_usertime(t1); + fprintf(stdout, "Time for %9d %s = %g ms\n", n, msg, + (t1[0] - t0[0]) * 1000.0 + (t1[1] - t0[1]) / 1000000.0); + fflush(stdout); + } +} + +/* + Output from SPARCstation 10, gcc -O bench.c gp_unix.c: + + Time for 10000000 integer adds = 113.502 ms + Time for 1000000 integer multiplies = 467.965 ms + Time for 1000000 integer divides = 594.328 ms + Time for 10000000 floating adds = 641.21 ms + Time for 10000000 floating multiplies = 643.357 ms + Time for 1000000 floating divides = 131.995 ms + Time for 10000000 float/int conversions = 602.061 ms + Time for 10000000 fast memory accesses = 201.048 ms + Time for 1000000 slow memory accesses = 552.606 ms + + Output from 486DX/25, wcl386 -oit bench.c gp_iwatc.c gp_msdos.c: + + Time for 10000000 integer adds = 490 ms + Time for 1000000 integer multiplies = 770 ms + Time for 1000000 integer divides = 1860 ms + Time for 10000000 floating adds = 4070 ms + Time for 10000000 floating multiplies = 4450 ms + Time for 1000000 floating divides = 2470 ms + Time for 10000000 float/int conversions = 25650 ms + Time for 10000000 fast memory accesses = 990 ms + Time for 1000000 slow memory accesses = 330 ms + + */ + +/* + The rest of this file contains a similar benchmark in PostScript. + + %! + /timer % <str> <N> <proc> timer + { bind 2 copy usertime mark 4 2 roll repeat cleartomark usertime exch sub + % Stack: str N proc dt + exch pop + (Time for ) print exch =only ( ) print exch =only (: ) print + =only ( ms + ) print flush + } def + + (x 20 integer adds) 5000 { 0 + 0 add 0 add 0 add 0 add 0 add 0 add 0 add 0 add 0 add 0 add + 0 add 0 add 0 add 0 add 0 add 0 add 0 add 0 add 0 add 0 add + pop } timer + + (x 20 integer multiplies) 5000 { 1 + 3 mul 3 mul 3 mul 3 mul 3 mul 3 mul 3 mul 3 mul 3 mul 3 mul + 3 mul 3 mul 3 mul 3 mul 3 mul 3 mul 3 mul 3 mul 3 mul 3 mul + pop } timer + + (x 20 integer divides) 5000 { 1000000000 + 3 idiv 3 idiv 3 idiv 3 idiv 3 idiv 3 idiv 3 idiv 3 idiv 3 idiv 3 idiv + 3 idiv 3 idiv 3 idiv 3 idiv 3 idiv 3 idiv 3 idiv 3 idiv 3 idiv 3 idiv + pop } timer + + (x 20 floating adds) 5000 { 0.0 + 1.0 add 1.0 add 1.0 add 1.0 add 1.0 add 1.0 add 1.0 add 1.0 add 1.0 add 1.0 add + 1.0 add 1.0 add 1.0 add 1.0 add 1.0 add 1.0 add 1.0 add 1.0 add 1.0 add 1.0 add + pop } timer + + (x 20 floating multiplies) 5000 { 1.0 + 2.3 mul 2.3 mul 2.3 mul 2.3 mul 2.3 mul 2.3 mul 2.3 mul 2.3 mul 2.3 mul 2.3 mul + 2.3 mul 2.3 mul 2.3 mul 2.3 mul 2.3 mul 2.3 mul 2.3 mul 2.3 mul 2.3 mul 2.3 mul + pop } timer + + (x 20 floating divides) 5000 { 1.0 + 2.3 div 2.3 div 2.3 div 2.3 div 2.3 div 2.3 div 2.3 div 2.3 div 2.3 div 2.3 div + 2.3 div 2.3 div 2.3 div 2.3 div 2.3 div 2.3 div 2.3 div 2.3 div 2.3 div 2.3 div + pop } timer + + (x 20 float/int conversions) 5000 { 12345.0 + cvi cvr cvi cvr cvi cvr cvi cvr cvi cvr + cvi cvr cvi cvr cvi cvr cvi cvr cvi cvr + pop } timer + + /S 2048 string def + (x 10000(byte) fast memory accesses) 1000 { + //S 1024 1000 getinterval //S copy pop + //S 1024 1000 getinterval //S copy pop + //S 1024 1000 getinterval //S copy pop + //S 1024 1000 getinterval //S copy pop + //S 1024 1000 getinterval //S copy pop + } timer + + /A [ 500 { 2048 string } repeat ] def + (x 500 x 2000(byte) slower memory accesses) 10 { + 0 1 499 { + //A exch get dup 1024 1000 getinterval exch copy pop + } for + } timer + + /Times-Roman findfont 36 scalefont setfont + currentcacheparams pop pop 0 1 index setcacheparams + /D [4 0 0 4 0 0] 1440 1440 <00 ff> makeimagedevice def + D setdevice + 72 72 translate + gsave 15 rotate + 0 0 moveto (A) show + (x 10 (A) show (cache)) 100 { + 0 0 moveto + (A) show (A) show (A) show (A) show (A) show + (A) show (A) show (A) show (A) show (A) show + } timer grestore + + 0 setcachelimit + gsave 10 rotate + (x 10 (A) show (no cache)) 10 { + 0 0 moveto + (A) show (A) show (A) show (A) show (A) show + (A) show (A) show (A) show (A) show (A) show + } timer grestore + + quit + + Results for SUN Sparc 2 (rated at 25 MIPS according to manual) + + ./gs + Now in gs_init.ps + TextAlphaBits defined GraphicsAlphaBits defined + Aladdin Ghostscript 3.50 (1995-9-24) + (c) 1995 Aladdin Enterprises, Menlo Park, CA. All rights reserved. This + software comes with NO WARRANTY: see the file PUBLIC for details. Leaving + gs_init.ps + GS>(ben1.c) run + Time for 5000 x 20 integer adds: 171 ms + Time for 5000 x 20 integer multiplies: 504 ms + Time for 5000 x 20 integer divides: 334 ms + Time for 5000 x 20 floating adds: 148 ms + Time for 5000 x 20 floating multiplies: 165 ms + Time for 5000 x 20 floating divides: 194 ms + Time for 5000 x 20 float/int conversions: 121 ms + Time for 1000 x 10000(byte) fast memory accesses: 112 ms + Time for 10 x 500 x 2000(byte) slower memory accesses: 236 ms + Loading NimbusRomanNo9L-Regular font from + [...]/n021003l.gsf... 1739080 414724 2564864 1251073 0 + done. Time for 100 x 10 (A) show (cache): 144 ms + Time for 10 x 10 (A) show (no cache): 538 ms + + Output from SPARCstation 10, gs 3.60 compiled with gcc -g -O -DDEBUG: + + gsnd bench.c + Aladdin Ghostscript 3.60 (1995-10-23) + Copyright (C) 1995 Aladdin Enterprises, Menlo Park, CA. All rights reserved. + This software comes with NO WARRANTY: see the file PUBLIC for details. + Time for 5000 x 20 integer adds: 192 ms + Time for 5000 x 20 integer multiplies: 561 ms + Time for 5000 x 20 integer divides: 396 ms + Time for 5000 x 20 floating adds: 202 ms + Time for 5000 x 20 floating multiplies: 247 ms + Time for 5000 x 20 floating divides: 243 ms + Time for 5000 x 20 float/int conversions: 157 ms + Time for 1000 x 10000(byte) fast memory accesses: 136 ms + Time for 10 x 500 x 2000(byte) slower memory accesses: 235 ms + Loading Temps-RomanSH font from /opt/home/peter/gs/fonts/soho/tersh___.pfb... 1759156 432729 2564864 1251025 0 done. + Time for 100 x 10 (A) show (cache): 161 ms + Time for 10 x 10 (A) show (no cache): 449 ms + + Output from 486DX/25, gs 2.6.1 compiled with wcc386 -oi[t]: + + gsndt bench.c + Initializing... done. + Ghostscript 2.6.1 (5/28/93) + Copyright (C) 1990-1993 Aladdin Enterprises, Menlo Park, CA. + All rights reserved. + Ghostscript comes with NO WARRANTY: see the file COPYING for details. + Time for 5000 x 20 integer adds: 550 ms + Time for 5000 x 20 integer multiplies: 940 ms + Time for 5000 x 20 integer divides: 880 ms + Time for 5000 x 20 floating adds: 550 ms + Time for 5000 x 20 floating multiplies: 660 ms + Time for 5000 x 20 floating divides: 930 ms + Time for 5000 x 20 float/int conversions: 830 ms + Time for 1000 x 10000(byte) fast memory accesses: 660 ms + Time for 10 x 500 x 2000(byte) slower memory accesses: 540 ms + Loading Temps-RomanSH font from c:\gs\fonts\softhorz\tersh___.pfb... 1298792 1207949 0 done. + Time for 100 x 10 (A) show (cache): 13520 ms + Time for 10 x 10 (A) show (no cache): 1310 ms + + Output from 486DX/25, gs 3.52 compiled with wcc386 -oi[t]: + + Aladdin Ghostscript 3.52 (1995-10-2) + Copyright (c) 1995 Aladdin Enterprises, Menlo Park, CA. All rights reserved. + This software comes with NO WARRANTY: see the file PUBLIC for details. + Time for 5000 x 20 integer adds: 660 ms + Time for 5000 x 20 integer multiplies: 1100 ms + Time for 5000 x 20 integer divides: 940 ms + Time for 5000 x 20 floating adds: 710 ms + Time for 5000 x 20 floating multiplies: 830 ms + Time for 5000 x 20 floating divides: 1040 ms + Time for 5000 x 20 float/int conversions: 820 ms + Time for 1000 x 10000(byte) fast memory accesses: 660 ms + Time for 10 x 500 x 1000(byte) slower memory accesses: 600 ms + Loading Temps-RomanSH font from c:\gs\fonts\softhorz\tersh___.pfb... 1678548 375231 2564864 1250964 0 done. + Time for 100 x 10 (A) show (cache): 2520 ms + Time for 10 x 10 (A) show (no cache): 1600 ms + + */ |