bench.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. /* pop (%!) .skipeof
  2. Copyright (C) 1989, 1995, 2000 Aladdin Enterprises. All rights reserved.
  3. This software is provided AS-IS with no warranty, either express or
  4. implied.
  5. This software is distributed under license and may not be copied,
  6. modified or distributed except as expressly authorized under the terms
  7. of the license contained in the file LICENSE in this distribution.
  8. For more information about licensing, please refer to
  9. http://www.ghostscript.com/licensing/. For information on
  10. commercial licensing, go to http://www.artifex.com/licensing/ or
  11. contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  12. San Rafael, CA 94903, U.S.A., +1(415)492-9861.
  13. */
  14. /* $Id: bench.c,v 1.7 2002/05/14 14:59:41 stefan Exp $ */
  15. /* Simple hardware benchmarking suite (C and PostScript) */
  16. #include "stdio_.h"
  17. #include <stdlib.h>
  18. /* Patchup for GS externals */
  19. FILE *gs_stdout;
  20. FILE *gs_stderr;
  21. FILE *gs_debug_out;
  22. const char gp_scratch_file_name_prefix[] = "gs_";
  23. static void
  24. capture_stdio(void)
  25. {
  26. gs_stdout = stdout;
  27. gs_stderr = stderr;
  28. gs_debug_out = stderr;
  29. }
  30. #include "gsio.h"
  31. #undef gs_stdout
  32. #undef gs_stderr
  33. #undef stdout
  34. #define stdout gs_stdout
  35. #undef stderr
  36. #define stderr gs_stderr
  37. FILE *
  38. gp_open_scratch_file(const char *prefix, char *fname, const char *mode)
  39. {
  40. return NULL;
  41. }
  42. void
  43. gp_set_printer_binary(int prnfno, int binary)
  44. {
  45. }
  46. void
  47. gs_to_exit(int n)
  48. {
  49. }
  50. #define eprintf_program_ident(f, pn, rn) (void)0
  51. void
  52. lprintf_file_and_line(FILE * f, const char *file, int line)
  53. {
  54. fprintf(f, "%s(%d): ", file, line);
  55. }
  56. /*
  57. * Read the CPU time (in seconds since an implementation-defined epoch)
  58. * into ptm[0], and fraction (in nanoseconds) into ptm[1].
  59. */
  60. #include "gp_unix.c"
  61. #undef stdout
  62. #define stdout gs_stdout
  63. #undef stderr
  64. #define stderr gs_stderr
  65. /* Loop unrolling macros */
  66. #define do10(x) x;x;x;x;x; x;x;x;x;x
  67. /* Define the actual benchmarks. */
  68. static int
  69. iadd(int a, int n, char **msg)
  70. {
  71. int b = 0, i;
  72. for (i = n / 20; --i >= 0;) {
  73. do10((b += a, b += i));
  74. }
  75. *msg = "integer adds";
  76. return b;
  77. }
  78. static int
  79. imul(int a, int n, char **msg)
  80. {
  81. int b = 1, i;
  82. for (i = n / 20; --i > 0;) {
  83. do10((b *= a, b *= i));
  84. }
  85. *msg = "integer multiplies";
  86. return b;
  87. }
  88. static int
  89. idiv(int a, int n, char **msg)
  90. {
  91. int b = 1, i;
  92. for (i = n / 20; --i > 0;) {
  93. b += 999999;
  94. do10((b /= a, b /= i));
  95. }
  96. *msg = "integer divides";
  97. return b;
  98. }
  99. static int
  100. fadd(float a, int n, char **msg)
  101. {
  102. float b = 0;
  103. int i;
  104. for (i = n / 10; --i >= 0;) {
  105. do10((b += a));
  106. }
  107. *msg = "floating adds";
  108. return b;
  109. }
  110. static int
  111. fmul(float a, int n, char **msg)
  112. {
  113. float b = 1;
  114. int i;
  115. for (i = n / 10; --i >= 0;) {
  116. do10((b *= a));
  117. }
  118. *msg = "floating multiplies";
  119. return b;
  120. }
  121. static int
  122. fdiv(float a, int n, char **msg)
  123. {
  124. float b = 1;
  125. int i;
  126. for (i = n / 10; --i >= 0;) {
  127. do10((b /= a));
  128. }
  129. *msg = "floating divides";
  130. return b;
  131. }
  132. static int
  133. fconv(int a, int n, char **msg)
  134. {
  135. int b[10];
  136. float f[10];
  137. int i;
  138. b[0] = a;
  139. for (i = n / 20; --i >= 0;)
  140. f[0] = b[0], f[1] = b[1], f[2] = b[2], f[3] = b[3], f[4] = b[4],
  141. f[5] = b[5], f[6] = b[6], f[7] = b[7], f[8] = b[8], f[9] = b[9],
  142. b[0] = f[1], b[1] = f[2], b[2] = f[3], b[3] = f[4], b[4] = f[5],
  143. b[5] = f[6], b[6] = f[7], b[7] = f[8], b[8] = f[9], b[9] = f[0];
  144. *msg = "float/int conversions";
  145. return b[0];
  146. }
  147. static int
  148. mfast(int *m, int n, char **msg)
  149. {
  150. int i;
  151. m[0] = n;
  152. for (i = n / 20; --i >= 0;)
  153. m[9] = m[8], m[8] = m[7], m[7] = m[6], m[6] = m[5], m[5] = m[4],
  154. m[4] = m[3], m[3] = m[2], m[2] = m[1], m[1] = m[0], m[0] = m[9];
  155. *msg = "fast memory accesses";
  156. return m[0];
  157. }
  158. static int
  159. mslow(int *m, int n, char **msg)
  160. {
  161. int *p;
  162. int i, k = 0;
  163. m[0] = n;
  164. for (i = n / 20; --i >= 0; k = (k + 397) & 0x3ffff)
  165. p = m + k,
  166. p[0] = p[100], p[20] = p[120], p[40] = p[140],
  167. p[60] = p[160], p[80] = p[180],
  168. p[200] = p[300], p[220] = p[320], p[240] = p[340],
  169. p[260] = p[360], p[280] = p[380];
  170. *msg = "slow memory accesses";
  171. return m[0];
  172. }
  173. int
  174. main(int argc, const char *argv[])
  175. {
  176. int i;
  177. int *mem = malloc(1100000);
  178. capture_stdio();
  179. for (i = 0;; ++i) {
  180. long t0[2], t1[2];
  181. char *msg;
  182. int n;
  183. gp_get_usertime(t0);
  184. switch (i) {
  185. case 0:
  186. iadd(0, n = 10000000, &msg);
  187. break;
  188. case 1:
  189. imul(1, n = 1000000, &msg);
  190. break;
  191. case 2:
  192. idiv(1, n = 1000000, &msg);
  193. break;
  194. case 3:
  195. fadd(3.14, n = 10000000, &msg);
  196. break;
  197. case 4:
  198. fmul(1.0000001, n = 10000000, &msg);
  199. break;
  200. case 5:
  201. fdiv(1.0000001, n = 1000000, &msg);
  202. break;
  203. case 6:
  204. fconv(12345, n = 10000000, &msg);
  205. break;
  206. case 7:
  207. mfast(mem, n = 10000000, &msg);
  208. break;
  209. case 8:
  210. mslow(mem, n = 1000000, &msg);
  211. break;
  212. default:
  213. free(mem);
  214. exit(0);
  215. }
  216. gp_get_usertime(t1);
  217. fprintf(stdout, "Time for %9d %s = %g ms\n", n, msg,
  218. (t1[0] - t0[0]) * 1000.0 + (t1[1] - t0[1]) / 1000000.0);
  219. fflush(stdout);
  220. }
  221. }
  222. /*
  223. Output from SPARCstation 10, gcc -O bench.c gp_unix.c:
  224. Time for 10000000 integer adds = 113.502 ms
  225. Time for 1000000 integer multiplies = 467.965 ms
  226. Time for 1000000 integer divides = 594.328 ms
  227. Time for 10000000 floating adds = 641.21 ms
  228. Time for 10000000 floating multiplies = 643.357 ms
  229. Time for 1000000 floating divides = 131.995 ms
  230. Time for 10000000 float/int conversions = 602.061 ms
  231. Time for 10000000 fast memory accesses = 201.048 ms
  232. Time for 1000000 slow memory accesses = 552.606 ms
  233. Output from 486DX/25, wcl386 -oit bench.c gp_iwatc.c gp_msdos.c:
  234. Time for 10000000 integer adds = 490 ms
  235. Time for 1000000 integer multiplies = 770 ms
  236. Time for 1000000 integer divides = 1860 ms
  237. Time for 10000000 floating adds = 4070 ms
  238. Time for 10000000 floating multiplies = 4450 ms
  239. Time for 1000000 floating divides = 2470 ms
  240. Time for 10000000 float/int conversions = 25650 ms
  241. Time for 10000000 fast memory accesses = 990 ms
  242. Time for 1000000 slow memory accesses = 330 ms
  243. */
  244. /*
  245. The rest of this file contains a similar benchmark in PostScript.
  246. %!
  247. /timer % <str> <N> <proc> timer
  248. { bind 2 copy usertime mark 4 2 roll repeat cleartomark usertime exch sub
  249. % Stack: str N proc dt
  250. exch pop
  251. (Time for ) print exch =only ( ) print exch =only (: ) print
  252. =only ( ms
  253. ) print flush
  254. } def
  255. (x 20 integer adds) 5000 { 0
  256. 0 add 0 add 0 add 0 add 0 add 0 add 0 add 0 add 0 add 0 add
  257. 0 add 0 add 0 add 0 add 0 add 0 add 0 add 0 add 0 add 0 add
  258. pop } timer
  259. (x 20 integer multiplies) 5000 { 1
  260. 3 mul 3 mul 3 mul 3 mul 3 mul 3 mul 3 mul 3 mul 3 mul 3 mul
  261. 3 mul 3 mul 3 mul 3 mul 3 mul 3 mul 3 mul 3 mul 3 mul 3 mul
  262. pop } timer
  263. (x 20 integer divides) 5000 { 1000000000
  264. 3 idiv 3 idiv 3 idiv 3 idiv 3 idiv 3 idiv 3 idiv 3 idiv 3 idiv 3 idiv
  265. 3 idiv 3 idiv 3 idiv 3 idiv 3 idiv 3 idiv 3 idiv 3 idiv 3 idiv 3 idiv
  266. pop } timer
  267. (x 20 floating adds) 5000 { 0.0
  268. 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
  269. 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
  270. pop } timer
  271. (x 20 floating multiplies) 5000 { 1.0
  272. 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
  273. 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
  274. pop } timer
  275. (x 20 floating divides) 5000 { 1.0
  276. 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
  277. 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
  278. pop } timer
  279. (x 20 float/int conversions) 5000 { 12345.0
  280. cvi cvr cvi cvr cvi cvr cvi cvr cvi cvr
  281. cvi cvr cvi cvr cvi cvr cvi cvr cvi cvr
  282. pop } timer
  283. /S 2048 string def
  284. (x 10000(byte) fast memory accesses) 1000 {
  285. //S 1024 1000 getinterval //S copy pop
  286. //S 1024 1000 getinterval //S copy pop
  287. //S 1024 1000 getinterval //S copy pop
  288. //S 1024 1000 getinterval //S copy pop
  289. //S 1024 1000 getinterval //S copy pop
  290. } timer
  291. /A [ 500 { 2048 string } repeat ] def
  292. (x 500 x 2000(byte) slower memory accesses) 10 {
  293. 0 1 499 {
  294. //A exch get dup 1024 1000 getinterval exch copy pop
  295. } for
  296. } timer
  297. /Times-Roman findfont 36 scalefont setfont
  298. currentcacheparams pop pop 0 1 index setcacheparams
  299. /D [4 0 0 4 0 0] 1440 1440 <00 ff> makeimagedevice def
  300. D setdevice
  301. 72 72 translate
  302. gsave 15 rotate
  303. 0 0 moveto (A) show
  304. (x 10 (A) show (cache)) 100 {
  305. 0 0 moveto
  306. (A) show (A) show (A) show (A) show (A) show
  307. (A) show (A) show (A) show (A) show (A) show
  308. } timer grestore
  309. 0 setcachelimit
  310. gsave 10 rotate
  311. (x 10 (A) show (no cache)) 10 {
  312. 0 0 moveto
  313. (A) show (A) show (A) show (A) show (A) show
  314. (A) show (A) show (A) show (A) show (A) show
  315. } timer grestore
  316. quit
  317. Results for SUN Sparc 2 (rated at 25 MIPS according to manual)
  318. ./gs
  319. Now in gs_init.ps
  320. TextAlphaBits defined GraphicsAlphaBits defined
  321. Aladdin Ghostscript 3.50 (1995-9-24)
  322. (c) 1995 Aladdin Enterprises, Menlo Park, CA. All rights reserved. This
  323. software comes with NO WARRANTY: see the file PUBLIC for details. Leaving
  324. gs_init.ps
  325. GS>(ben1.c) run
  326. Time for 5000 x 20 integer adds: 171 ms
  327. Time for 5000 x 20 integer multiplies: 504 ms
  328. Time for 5000 x 20 integer divides: 334 ms
  329. Time for 5000 x 20 floating adds: 148 ms
  330. Time for 5000 x 20 floating multiplies: 165 ms
  331. Time for 5000 x 20 floating divides: 194 ms
  332. Time for 5000 x 20 float/int conversions: 121 ms
  333. Time for 1000 x 10000(byte) fast memory accesses: 112 ms
  334. Time for 10 x 500 x 2000(byte) slower memory accesses: 236 ms
  335. Loading NimbusRomanNo9L-Regular font from
  336. [...]/n021003l.gsf... 1739080 414724 2564864 1251073 0
  337. done. Time for 100 x 10 (A) show (cache): 144 ms
  338. Time for 10 x 10 (A) show (no cache): 538 ms
  339. Output from SPARCstation 10, gs 3.60 compiled with gcc -g -O -DDEBUG:
  340. gsnd bench.c
  341. Aladdin Ghostscript 3.60 (1995-10-23)
  342. Copyright (C) 1995 Aladdin Enterprises, Menlo Park, CA. All rights reserved.
  343. This software comes with NO WARRANTY: see the file PUBLIC for details.
  344. Time for 5000 x 20 integer adds: 192 ms
  345. Time for 5000 x 20 integer multiplies: 561 ms
  346. Time for 5000 x 20 integer divides: 396 ms
  347. Time for 5000 x 20 floating adds: 202 ms
  348. Time for 5000 x 20 floating multiplies: 247 ms
  349. Time for 5000 x 20 floating divides: 243 ms
  350. Time for 5000 x 20 float/int conversions: 157 ms
  351. Time for 1000 x 10000(byte) fast memory accesses: 136 ms
  352. Time for 10 x 500 x 2000(byte) slower memory accesses: 235 ms
  353. Loading Temps-RomanSH font from /opt/home/peter/gs/fonts/soho/tersh___.pfb... 1759156 432729 2564864 1251025 0 done.
  354. Time for 100 x 10 (A) show (cache): 161 ms
  355. Time for 10 x 10 (A) show (no cache): 449 ms
  356. Output from 486DX/25, gs 2.6.1 compiled with wcc386 -oi[t]:
  357. gsndt bench.c
  358. Initializing... done.
  359. Ghostscript 2.6.1 (5/28/93)
  360. Copyright (C) 1990-1993 Aladdin Enterprises, Menlo Park, CA.
  361. All rights reserved.
  362. Ghostscript comes with NO WARRANTY: see the file COPYING for details.
  363. Time for 5000 x 20 integer adds: 550 ms
  364. Time for 5000 x 20 integer multiplies: 940 ms
  365. Time for 5000 x 20 integer divides: 880 ms
  366. Time for 5000 x 20 floating adds: 550 ms
  367. Time for 5000 x 20 floating multiplies: 660 ms
  368. Time for 5000 x 20 floating divides: 930 ms
  369. Time for 5000 x 20 float/int conversions: 830 ms
  370. Time for 1000 x 10000(byte) fast memory accesses: 660 ms
  371. Time for 10 x 500 x 2000(byte) slower memory accesses: 540 ms
  372. Loading Temps-RomanSH font from c:\gs\fonts\softhorz\tersh___.pfb... 1298792 1207949 0 done.
  373. Time for 100 x 10 (A) show (cache): 13520 ms
  374. Time for 10 x 10 (A) show (no cache): 1310 ms
  375. Output from 486DX/25, gs 3.52 compiled with wcc386 -oi[t]:
  376. Aladdin Ghostscript 3.52 (1995-10-2)
  377. Copyright (c) 1995 Aladdin Enterprises, Menlo Park, CA. All rights reserved.
  378. This software comes with NO WARRANTY: see the file PUBLIC for details.
  379. Time for 5000 x 20 integer adds: 660 ms
  380. Time for 5000 x 20 integer multiplies: 1100 ms
  381. Time for 5000 x 20 integer divides: 940 ms
  382. Time for 5000 x 20 floating adds: 710 ms
  383. Time for 5000 x 20 floating multiplies: 830 ms
  384. Time for 5000 x 20 floating divides: 1040 ms
  385. Time for 5000 x 20 float/int conversions: 820 ms
  386. Time for 1000 x 10000(byte) fast memory accesses: 660 ms
  387. Time for 10 x 500 x 1000(byte) slower memory accesses: 600 ms
  388. Loading Temps-RomanSH font from c:\gs\fonts\softhorz\tersh___.pfb... 1678548 375231 2564864 1250964 0 done.
  389. Time for 100 x 10 (A) show (cache): 2520 ms
  390. Time for 10 x 10 (A) show (no cache): 1600 ms
  391. */