count.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. /***********************************************************************
  2. *
  3. * This file contains functions for the automatic complexity calculation
  4. * $Id $
  5. *************************************************************************/
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include "typedef.h"
  10. #include "count.h"
  11. /* Global counter variable for calculation of complexity weight */
  12. BASIC_OP multiCounter[MAXCOUNTERS];
  13. int currCounter=0; /* Zero equals global counter */
  14. /*BASIC_OP counter;*/
  15. const BASIC_OP op_weight =
  16. {
  17. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  18. 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  19. 3, 3, 3, 4, 15, 18, 30, 1, 2, 1, 2, 2
  20. };
  21. /* function prototypes */
  22. Word32 TotalWeightedOperation (void);
  23. Word32 DeltaWeightedOperation (void);
  24. /* local variable */
  25. #if WMOPS
  26. /* Counters for separating counting for different objects */
  27. static int maxCounter=0;
  28. static char* objectName[MAXCOUNTERS+1];
  29. static Word16 fwc_corr[MAXCOUNTERS+1];
  30. #define NbFuncMax 1024
  31. static Word16 funcid[MAXCOUNTERS], nbframe[MAXCOUNTERS];
  32. static Word32 glob_wc[MAXCOUNTERS], wc[MAXCOUNTERS][NbFuncMax];
  33. static float total_wmops[MAXCOUNTERS];
  34. static Word32 LastWOper[MAXCOUNTERS];
  35. static char* my_strdup(const char *s)
  36. /*
  37. * duplicates UNIX function strdup() which is not ANSI standard:
  38. * -- malloc() memory area big enough to hold the string s
  39. * -- copy string into new area
  40. * -- return pointer to new area
  41. *
  42. * returns NULL if either s==NULL or malloc() fails
  43. */
  44. {
  45. char *dup;
  46. if (s == NULL)
  47. return NULL;
  48. /* allocate memory for copy of ID string (including string terminator) */
  49. /* NOTE: the ID strings will never be deallocated because there is no
  50. way to "destroy" a counter that is not longer needed */
  51. if ((dup = (char *) wmalloc(strlen(s)+1)) == NULL)
  52. return NULL;
  53. return strcpy(dup, s);
  54. }
  55. #endif
  56. int getCounterId(char *objectNameArg)
  57. {
  58. #if WMOPS
  59. if(maxCounter>=MAXCOUNTERS-1) return 0;
  60. objectName[++maxCounter]=my_strdup(objectNameArg);
  61. return maxCounter;
  62. #else
  63. return 0; /* Dummy */
  64. #endif
  65. }
  66. void setCounter(int counterId)
  67. {
  68. #if WMOPS
  69. if(counterId>maxCounter || counterId<0)
  70. {
  71. currCounter=0;
  72. return;
  73. }
  74. currCounter=counterId;
  75. #endif
  76. }
  77. #if WMOPS
  78. static Word32 WMOPS_frameStat()
  79. /* calculate the WMOPS seen so far and update the global
  80. per-frame maximum (glob_wc)
  81. */
  82. {
  83. Word32 tot;
  84. tot = TotalWeightedOperation ();
  85. if (tot > glob_wc[currCounter])
  86. glob_wc[currCounter] = tot;
  87. /* check if fwc() was forgotten at end of last frame */
  88. if (tot > LastWOper[currCounter]) {
  89. if (!fwc_corr[currCounter]) {
  90. wfprintf(stderr,
  91. "count: operations counted after last fwc() for '%s'; "
  92. "-> fwc() called\n",
  93. objectName[currCounter]?objectName[currCounter]:"");
  94. }
  95. fwc();
  96. }
  97. return tot;
  98. }
  99. static void WMOPS_clearMultiCounter()
  100. {
  101. Word16 i;
  102. Word32 *ptr = (Word32 *) &multiCounter[currCounter];
  103. for (i = 0; i < (sizeof (multiCounter[currCounter])/ sizeof (Word32)); i++)
  104. {
  105. *ptr++ = 0;
  106. }
  107. }
  108. #endif
  109. Word32 TotalWeightedOperation ()
  110. {
  111. #if WMOPS
  112. Word16 i;
  113. Word32 tot, *ptr, *ptr2;
  114. tot = 0;
  115. ptr = (Word32 *) &multiCounter[currCounter];
  116. ptr2 = (Word32 *) &op_weight;
  117. for (i = 0; i < (sizeof (multiCounter[currCounter])/ sizeof (Word32)); i++)
  118. {
  119. tot += ((*ptr++) * (*ptr2++));
  120. }
  121. return ((Word32) tot);
  122. #else
  123. return 0; /* Dummy */
  124. #endif
  125. }
  126. Word32 DeltaWeightedOperation ()
  127. {
  128. #if WMOPS
  129. Word32 NewWOper, delta;
  130. NewWOper = TotalWeightedOperation ();
  131. delta = NewWOper - LastWOper[currCounter];
  132. LastWOper[currCounter] = NewWOper;
  133. return (delta);
  134. #else
  135. return 0; /* Dummy */
  136. #endif
  137. }
  138. void move16 (void)
  139. {
  140. #if WMOPS
  141. multiCounter[currCounter].DataMove16++;
  142. #endif
  143. }
  144. void move32 (void)
  145. {
  146. #if WMOPS
  147. multiCounter[currCounter].DataMove32++;
  148. #endif
  149. }
  150. void test (void)
  151. {
  152. #if WMOPS
  153. multiCounter[currCounter].Test++;
  154. #endif
  155. }
  156. void logic16 (void)
  157. {
  158. #if WMOPS
  159. multiCounter[currCounter].Logic16++;
  160. #endif
  161. }
  162. void logic32 (void)
  163. {
  164. #if WMOPS
  165. multiCounter[currCounter].Logic32++;
  166. #endif
  167. }
  168. void Init_WMOPS_counter (void)
  169. {
  170. #if WMOPS
  171. Word16 i;
  172. /* reset function weight operation counter variable */
  173. for (i = 0; i < NbFuncMax; i++)
  174. wc[currCounter][i] = (Word32) 0;
  175. glob_wc[currCounter] = 0;
  176. nbframe[currCounter] = 0;
  177. total_wmops[currCounter] = 0.0;
  178. /* initially clear all counters */
  179. WMOPS_clearMultiCounter();
  180. LastWOper[currCounter] = 0;
  181. funcid[currCounter] = 0;
  182. #endif
  183. }
  184. void Reset_WMOPS_counter (void)
  185. {
  186. #if WMOPS
  187. Word32 tot = WMOPS_frameStat();
  188. /* increase the frame counter --> a frame is counted WHEN IT BEGINS */
  189. nbframe[currCounter]++;
  190. /* add wmops used in last frame to count, then reset counter */
  191. /* (in first frame, this is a no-op */
  192. total_wmops[currCounter] += ((float) tot) * 0.00005;
  193. /* clear counter before new frame starts */
  194. WMOPS_clearMultiCounter();
  195. LastWOper[currCounter] = 0;
  196. funcid[currCounter] = 0; /* new frame, set function id to zero */
  197. #endif
  198. }
  199. Word32 fwc (void) /* function worst case */
  200. {
  201. #if WMOPS
  202. Word32 tot;
  203. tot = DeltaWeightedOperation ();
  204. if (tot > wc[currCounter][funcid[currCounter]])
  205. wc[currCounter][funcid[currCounter]] = tot;
  206. funcid[currCounter]++;
  207. return (tot);
  208. #else
  209. return 0; /* Dummy */
  210. #endif
  211. }
  212. void WMOPS_output (Word16 dtx_mode)
  213. {
  214. #if WMOPS
  215. Word16 i;
  216. Word32 tot, tot_wm, tot_wc;
  217. /* get operations since last reset (or init),
  218. but do not update the counters (except the glob_wc[] maximum)
  219. so output CAN be called in each frame without problems.
  220. The frame counter is NOT updated!
  221. */
  222. tot = WMOPS_frameStat();
  223. tot_wm = total_wmops[currCounter] + ((float) tot) * 0.00005;
  224. wfprintf (stdout, "%10s:WMOPS=%.3f",
  225. objectName[currCounter]?objectName[currCounter]:"",
  226. ((float) tot) * 0.00005);
  227. if (nbframe[currCounter] != 0)
  228. wfprintf (stdout, " Average=%.3f",
  229. tot_wm / (float) nbframe[currCounter]);
  230. wfprintf (stdout, " WorstCase=%.3f",
  231. ((float) glob_wc[currCounter]) * 0.00005);
  232. /* Worst worst case printed only when not in DTX mode */
  233. if (dtx_mode == 0)
  234. {
  235. tot_wc = 0L;
  236. for (i = 0; i < funcid[currCounter]; i++)
  237. tot_wc += wc[currCounter][i];
  238. wfprintf (stdout, " WorstWC=%.3f", ((float) tot_wc) * 0.00005);
  239. }
  240. wfprintf (stdout, " (%d frames)\n", nbframe[currCounter]);
  241. #endif
  242. }