(no commit message)
[openjpeg.git] / libopenjpeg / profile.c
1 /*
2  * Copyright (c) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes@c-s.fr>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24  * POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 /**
28  * Adapted from Herb Marselas
29 "Profiling, Data Analysis, Scalability, and Magic Numbers: Meeting the Minimum System Requirements for AGE OF EMPIRES 2: THE AGE OF KINGS"
30 Game Developer magazine
31 June, 2000 issue.
32 */
33
34 #include "profile.h"
35 #include <string.h>
36 #include <stdio.h>
37 #include <time.h>
38 //==============================================================================
39 static OPJ_PROFILE_LIST group_list [PGROUP_LASTGROUP];
40
41 //==============================================================================
42 static void GetTimeStamp(OPJ_UINT32 *pdwtime);
43
44 //==============================================================================
45 #define SetMajorSection(entry, major) \
46         { group_list[ entry ].section = entry ; \
47           group_list[ entry ].sectionName = #major ; }
48
49 //==============================================================================
50 void _ProfInit(void)
51 {
52    // clear everything out
53    memset(group_list, 0, sizeof(group_list));
54
55    // set groups and parents for timing
56    SetMajorSection(PGROUP_DWT,PGROUP_DWT);
57    SetMajorSection(PGROUP_T1, PGROUP_T1);
58    SetMajorSection(PGROUP_T2, PGROUP_T2);
59 } // ProfInit
60
61 //==============================================================================
62 void _ProfStart (OPJ_PROFILE_GROUP group)
63 {
64    // make sure this hasn't been incorrectly started twice
65    if (group_list[group].start)
66    {
67       return;
68    }
69
70    // get the start time
71    GetTimeStamp(&(group_list[group].start));
72
73 } // _ProfStart
74
75 //==============================================================================
76 void _ProfStop(OPJ_PROFILE_GROUP group)
77 {
78    // make sure we called start first
79    if (!group_list[group].start)
80    {
81       return;
82    }
83
84    // get ending time
85    GetTimeStamp(&(group_list[group].end));
86
87    // calculate this latest elapsed interval
88    group_list[group].total_time += group_list[group].end - group_list[group].start;
89
90    // reset starting time
91    group_list[group].start = 0;
92
93    // incr the number of calls made
94    ++group_list[group].totalCalls;
95
96 } // _ProfStop
97
98 //==============================================================================
99 #define proftracef(id,totalTime) \
100         fprintf(p, #id "\t%u\t\t%6.6f\t\t%12.6f\t%2.2f%%\n",  \
101                 group_list[ id ].totalCalls, \
102                (OPJ_FLOAT64) group_list[ id ].total_time / CLOCKS_PER_SEC, \
103                ((OPJ_FLOAT64) group_list[ id ].total_time / (group_list[ id ].totalCalls ? group_list[ id ].totalCalls : 1)), \
104                            ((OPJ_FLOAT64) group_list[ id ].total_time / totalTime * 100))
105
106 #define proftracep(id,totalTime) \
107         printf(#id "\t%u\t\t%6.6f\t\t%12.6f\t%2.2f%%\n",  \
108                 group_list[ id ].totalCalls, \
109                (OPJ_FLOAT64) group_list[ id ].total_time / CLOCKS_PER_SEC, \
110                                                          ((OPJ_FLOAT64) group_list[ id ].total_time  / (group_list[ id ].totalCalls ? group_list[ id ].totalCalls : 1)), \
111                            ((OPJ_FLOAT64) group_list[ id ].total_time / totalTime * 100))
112
113 //==============================================================================
114 void _ProfSave(const OPJ_CHAR * pFileName)
115 {
116         FILE *p = fopen(pFileName, "wt");
117         OPJ_FLOAT64 totalTime = 0.;
118         OPJ_UINT32 i;
119
120         if (!p)
121         {
122                 return;
123         }
124
125         for 
126                 (i=0;i<PGROUP_LASTGROUP;++i)
127         {
128                 totalTime += group_list[i].total_time;
129         }
130
131         fputs("\n\nProfile Data:\n", p);
132         fputs("description\tnb calls\ttotal time (sec)\ttime per call\t%% of section\n", p);
133
134         proftracef(PGROUP_DWT,totalTime);
135         proftracef(PGROUP_T1,totalTime);
136         proftracef(PGROUP_T2,totalTime);        
137
138    fputs("=== end of profile list ===\n\n", p);
139
140    fclose(p);
141
142 } // _ProfSave
143
144 //==============================================================================
145 void _ProfPrint(void)
146 {
147         OPJ_FLOAT64 totalTime = 0.;
148         OPJ_UINT32 i;
149
150         for 
151                 (i=0;i<PGROUP_LASTGROUP;++i)
152         {
153                 totalTime += group_list[i].total_time;
154         }
155
156         printf("\n\nProfile Data:\n");
157         printf("description\tnb calls\ttotal time (sec)\ttime per call\t%% of section\n");
158
159         proftracep(PGROUP_RATE, totalTime);
160         proftracep(PGROUP_DC_SHIFT, totalTime);
161         proftracep(PGROUP_MCT, totalTime);
162         proftracep(PGROUP_DWT, totalTime);
163         proftracep(PGROUP_T1, totalTime);
164         proftracep(PGROUP_T2, totalTime);
165
166         printf("\nTotal time: %6.3f second(s)\n", totalTime / CLOCKS_PER_SEC);
167
168   printf("=== end of profile list ===\n\n");
169
170 } // _ProfPrint
171
172 //==============================================================================
173 static void GetTimeStamp(unsigned *time)
174 {
175    *time = clock();
176
177 } // GetTimeStamp