whetstone.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. /*
  2. * C Converted Whetstone Double Precision Benchmark
  3. * Version 1.2 22 March 1998
  4. *
  5. * (c) Copyright 1998 Painter Engineering, Inc.
  6. * All Rights Reserved.
  7. *
  8. * Permission is granted to use, duplicate, and
  9. * publish this text and program as long as it
  10. * includes this entire comment block and limited
  11. * rights reference.
  12. *
  13. * Converted by Rich Painter, Painter Engineering, Inc. based on the
  14. * www.netlib.org benchmark/whetstoned version obtained 16 March 1998.
  15. *
  16. * A novel approach was used here to keep the look and feel of the
  17. * FORTRAN version. Altering the FORTRAN-based array indices,
  18. * starting at element 1, to start at element 0 for C, would require
  19. * numerous changes, including decrementing the variable indices by 1.
  20. * Instead, the array E1[] was declared 1 element larger in C. This
  21. * allows the FORTRAN index range to function without any literal or
  22. * variable indices changes. The array element E1[0] is simply never
  23. * used and does not alter the benchmark results.
  24. *
  25. * The major FORTRAN comment blocks were retained to minimize
  26. * differences between versions. Modules N5 and N12, like in the
  27. * FORTRAN version, have been eliminated here.
  28. *
  29. * An optional command-line argument has been provided [-c] to
  30. * offer continuous repetition of the entire benchmark.
  31. * An optional argument for setting an alternate LOOP count is also
  32. * provided. Define PRINTOUT to cause the POUT() function to print
  33. * outputs at various stages. Final timing measurements should be
  34. * made with the PRINTOUT undefined.
  35. *
  36. * Questions and comments may be directed to the author at
  37. * r.painter@ieee.org
  38. */
  39. /*
  40. C**********************************************************************
  41. C Benchmark #2 -- Double Precision Whetstone (A001)
  42. C
  43. C o This is a REAL*8 version of
  44. C the Whetstone benchmark program.
  45. C
  46. C o DO-loop semantics are ANSI-66 compatible.
  47. C
  48. C o Final measurements are to be made with all
  49. C WRITE statements and FORMAT sttements removed.
  50. C
  51. C**********************************************************************
  52. */
  53. /* standard C library headers required */
  54. #include <stdlib.h>
  55. #include <stdio.h>
  56. #include <string.h>
  57. #include <math.h>
  58. /* the following is optional depending on the timing function used */
  59. #include <time.h>
  60. /* map the FORTRAN math functions, etc. to the C versions */
  61. #define DSIN sin
  62. #define DCOS cos
  63. #define DATAN atan
  64. #define DLOG log
  65. #define DEXP exp
  66. #define DSQRT sqrt
  67. #define IF if
  68. /* function prototypes */
  69. void POUT(long N, long J, long K, double X1, double X2, double X3, double X4);
  70. void PA(double E[]);
  71. void P0(void);
  72. void P3(double X, double Y, double *Z);
  73. #define USAGE "usage: whetdc [-c] [loops]\n"
  74. /*
  75. COMMON T,T1,T2,E1(4),J,K,L
  76. */
  77. double T,T1,T2,E1[5];
  78. int J,K,L;
  79. int
  80. main(int argc, char *argv[])
  81. {
  82. /* used in the FORTRAN version */
  83. long I;
  84. long N1, N2, N3, N4, N6, N7, N8, N9, N10, N11;
  85. double X1,X2,X3,X4,X,Y,Z;
  86. long LOOP;
  87. int II, JJ;
  88. /* added for this version */
  89. long loopstart;
  90. long startsec, finisec;
  91. float KIPS;
  92. int continuous;
  93. loopstart = 1000; /* see the note about LOOP below */
  94. continuous = 0;
  95. II = 1; /* start at the first arg (temp use of II here) */
  96. while (II < argc) {
  97. if (strncmp(argv[II], "-c", 2) == 0 || argv[II][0] == 'c') {
  98. continuous = 1;
  99. } else if (atol(argv[II]) > 0) {
  100. loopstart = atol(argv[II]);
  101. } else {
  102. fprintf(stderr, USAGE);
  103. return(1);
  104. }
  105. II++;
  106. }
  107. LCONT:
  108. /*
  109. C
  110. C Start benchmark timing at this point.
  111. C
  112. */
  113. startsec = time(0);
  114. /*
  115. C
  116. C The actual benchmark starts here.
  117. C
  118. */
  119. T = .499975;
  120. T1 = 0.50025;
  121. T2 = 2.0;
  122. /*
  123. C
  124. C With loopcount LOOP=10, one million Whetstone instructions
  125. C will be executed in EACH MAJOR LOOP..A MAJOR LOOP IS EXECUTED
  126. C 'II' TIMES TO INCREASE WALL-CLOCK TIMING ACCURACY.
  127. C
  128. LOOP = 1000;
  129. */
  130. LOOP = loopstart;
  131. II = 1;
  132. JJ = 1;
  133. IILOOP:
  134. N1 = 0;
  135. N2 = 12 * LOOP;
  136. N3 = 14 * LOOP;
  137. N4 = 345 * LOOP;
  138. N6 = 210 * LOOP;
  139. N7 = 32 * LOOP;
  140. N8 = 899 * LOOP;
  141. N9 = 616 * LOOP;
  142. N10 = 0;
  143. N11 = 93 * LOOP;
  144. /*
  145. C
  146. C Module 1: Simple identifiers
  147. C
  148. */
  149. X1 = 1.0;
  150. X2 = -1.0;
  151. X3 = -1.0;
  152. X4 = -1.0;
  153. for (I = 1; I <= N1; I++) {
  154. X1 = (X1 + X2 + X3 - X4) * T;
  155. X2 = (X1 + X2 - X3 + X4) * T;
  156. X3 = (X1 - X2 + X3 + X4) * T;
  157. X4 = (-X1+ X2 + X3 + X4) * T;
  158. }
  159. #ifdef PRINTOUT
  160. IF (JJ==II)POUT(N1,N1,N1,X1,X2,X3,X4);
  161. #endif
  162. /*
  163. C
  164. C Module 2: Array elements
  165. C
  166. */
  167. E1[1] = 1.0;
  168. E1[2] = -1.0;
  169. E1[3] = -1.0;
  170. E1[4] = -1.0;
  171. for (I = 1; I <= N2; I++) {
  172. E1[1] = ( E1[1] + E1[2] + E1[3] - E1[4]) * T;
  173. E1[2] = ( E1[1] + E1[2] - E1[3] + E1[4]) * T;
  174. E1[3] = ( E1[1] - E1[2] + E1[3] + E1[4]) * T;
  175. E1[4] = (-E1[1] + E1[2] + E1[3] + E1[4]) * T;
  176. }
  177. #ifdef PRINTOUT
  178. IF (JJ==II)POUT(N2,N3,N2,E1[1],E1[2],E1[3],E1[4]);
  179. #endif
  180. /*
  181. C
  182. C Module 3: Array as parameter
  183. C
  184. */
  185. for (I = 1; I <= N3; I++)
  186. PA(E1);
  187. #ifdef PRINTOUT
  188. IF (JJ==II)POUT(N3,N2,N2,E1[1],E1[2],E1[3],E1[4]);
  189. #endif
  190. /*
  191. C
  192. C Module 4: Conditional jumps
  193. C
  194. */
  195. J = 1;
  196. for (I = 1; I <= N4; I++) {
  197. if (J == 1)
  198. J = 2;
  199. else
  200. J = 3;
  201. if (J > 2)
  202. J = 0;
  203. else
  204. J = 1;
  205. if (J < 1)
  206. J = 1;
  207. else
  208. J = 0;
  209. }
  210. #ifdef PRINTOUT
  211. IF (JJ==II)POUT(N4,J,J,X1,X2,X3,X4);
  212. #endif
  213. /*
  214. C
  215. C Module 5: Omitted
  216. C Module 6: Integer arithmetic
  217. C
  218. */
  219. J = 1;
  220. K = 2;
  221. L = 3;
  222. for (I = 1; I <= N6; I++) {
  223. J = J * (K-J) * (L-K);
  224. K = L * K - (L-J) * K;
  225. L = (L-K) * (K+J);
  226. E1[L-1] = J + K + L;
  227. E1[K-1] = J * K * L;
  228. }
  229. #ifdef PRINTOUT
  230. IF (JJ==II)POUT(N6,J,K,E1[1],E1[2],E1[3],E1[4]);
  231. #endif
  232. /*
  233. C
  234. C Module 7: Trigonometric functions
  235. C
  236. */
  237. X = 0.5;
  238. Y = 0.5;
  239. for (I = 1; I <= N7; I++) {
  240. X = T * DATAN(T2*DSIN(X)*DCOS(X)/(DCOS(X+Y)+DCOS(X-Y)-1.0));
  241. Y = T * DATAN(T2*DSIN(Y)*DCOS(Y)/(DCOS(X+Y)+DCOS(X-Y)-1.0));
  242. }
  243. #ifdef PRINTOUT
  244. IF (JJ==II)POUT(N7,J,K,X,X,Y,Y);
  245. #endif
  246. /*
  247. C
  248. C Module 8: Procedure calls
  249. C
  250. */
  251. X = 1.0;
  252. Y = 1.0;
  253. Z = 1.0;
  254. for (I = 1; I <= N8; I++)
  255. P3(X,Y,&Z);
  256. #ifdef PRINTOUT
  257. IF (JJ==II)POUT(N8,J,K,X,Y,Z,Z);
  258. #endif
  259. /*
  260. C
  261. C Module 9: Array references
  262. C
  263. */
  264. J = 1;
  265. K = 2;
  266. L = 3;
  267. E1[1] = 1.0;
  268. E1[2] = 2.0;
  269. E1[3] = 3.0;
  270. for (I = 1; I <= N9; I++)
  271. P0();
  272. #ifdef PRINTOUT
  273. IF (JJ==II)POUT(N9,J,K,E1[1],E1[2],E1[3],E1[4]);
  274. #endif
  275. /*
  276. C
  277. C Module 10: Integer arithmetic
  278. C
  279. */
  280. J = 2;
  281. K = 3;
  282. for (I = 1; I <= N10; I++) {
  283. J = J + K;
  284. K = J + K;
  285. J = K - J;
  286. K = K - J - J;
  287. }
  288. #ifdef PRINTOUT
  289. IF (JJ==II)POUT(N10,J,K,X1,X2,X3,X4);
  290. #endif
  291. /*
  292. C
  293. C Module 11: Standard functions
  294. C
  295. */
  296. X = 0.75;
  297. for (I = 1; I <= N11; I++)
  298. X = DSQRT(DEXP(DLOG(X)/T1));
  299. #ifdef PRINTOUT
  300. IF (JJ==II)POUT(N11,J,K,X,X,X,X);
  301. #endif
  302. /*
  303. C
  304. C THIS IS THE END OF THE MAJOR LOOP.
  305. C
  306. */
  307. if (++JJ <= II)
  308. goto IILOOP;
  309. /*
  310. C
  311. C Stop benchmark timing at this point.
  312. C
  313. */
  314. finisec = time(0);
  315. /*
  316. C----------------------------------------------------------------
  317. C Performance in Whetstone KIP's per second is given by
  318. C
  319. C (100*LOOP*II)/TIME
  320. C
  321. C where TIME is in seconds.
  322. C--------------------------------------------------------------------
  323. */
  324. printf("\n");
  325. if (finisec-startsec <= 0) {
  326. printf("Insufficient duration- Increase the LOOP count\n");
  327. return(1);
  328. }
  329. printf("Loops: %ld, Iterations: %d, Duration: %ld sec.\n",
  330. LOOP, II, finisec-startsec);
  331. KIPS = (100.0*LOOP*II)/(float)(finisec-startsec);
  332. if (KIPS >= 1000.0)
  333. printf("C Converted Double Precision Whetstones: %.1f MIPS\n", KIPS/1000.0);
  334. else
  335. printf("C Converted Double Precision Whetstones: %.1f KIPS\n", KIPS);
  336. if (continuous)
  337. goto LCONT;
  338. return(0);
  339. }
  340. void
  341. PA(double E[])
  342. {
  343. J = 0;
  344. L10:
  345. E[1] = ( E[1] + E[2] + E[3] - E[4]) * T;
  346. E[2] = ( E[1] + E[2] - E[3] + E[4]) * T;
  347. E[3] = ( E[1] - E[2] + E[3] + E[4]) * T;
  348. E[4] = (-E[1] + E[2] + E[3] + E[4]) / T2;
  349. J += 1;
  350. if (J < 6)
  351. goto L10;
  352. }
  353. void
  354. P0(void)
  355. {
  356. E1[J] = E1[K];
  357. E1[K] = E1[L];
  358. E1[L] = E1[J];
  359. }
  360. void
  361. P3(double X, double Y, double *Z)
  362. {
  363. double X1, Y1;
  364. X1 = X;
  365. Y1 = Y;
  366. X1 = T * (X1 + Y1);
  367. Y1 = T * (X1 + Y1);
  368. *Z = (X1 + Y1) / T2;
  369. }
  370. #ifdef PRINTOUT
  371. void
  372. POUT(long N, long J, long K, double X1, double X2, double X3, double X4)
  373. {
  374. printf("%7ld %7ld %7ld %12.4e %12.4e %12.4e %12.4e\n",
  375. N, J, K, X1, X2, X3, X4);
  376. }
  377. #endif