root/branches/atorf/personal playground/NXCProfiler/Profiler01.nxc @ 850

Revision 850, 7.3 KB (checked in by atorf, 3 years ago)

Progress and first example for profiler…

Line 
1//#!C
2/*
3%
4% Core of the NXC-Profiler!
5% Declares various functions and macros to be included to NXC programs in order
6% to get "live" runtime performance analysis.
7%
8%   see http://forums.nxtasy.org/index.php?showtopic=4496
9%
10%
11% Signature
12%   Author: Linus Atorf (see AUTHORS)
13%   Date: 2009/12/07
14%   Version: 0.1
15%   License: GPLv3
16%
17%
18% ***********************************************************************************************
19% *  This file is part of the RWTH - Mindstorms NXT Toolbox.                                    *
20% *                                                                                             *
21% *  The RWTH - Mindstorms NXT Toolbox is free software: you can redistribute it and/or modify  *
22% *  it under the terms of the GNU General Public License as published by the Free Software     *
23% *  Foundation, either version 3 of the License, or (at your option) any later version.        *
24% *                                                                                             *
25% *  The RWTH - Mindstorms NXT Toolbox is distributed in the hope that it will be useful,       *
26% *  but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS  *
27% *  FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
28% *                                                                                             *
29% *  You should have received a copy of the GNU General Public License along with the           *
30% *  RWTH - Mindstorms NXT Toolbox. If not, see <http://www.gnu.org/licenses/>.                 *
31% ***********************************************************************************************
32*/
33
34//useful macros:
35//#if __FIRMWARE_VERSION > 107
36//#ifdef __ENHANCED_FIRMWARE
37//__LINE__
38
39
40// include-guard
41#ifndef __PROFILER01_NXC__
42#define __PROFILER01_NXC__
43
44
45
46//TEST: just a personal check to see if this compiles
47//#define __LOCAL_COMPILE_FAKE_TEST
48//#define PROFILER_ENABLE
49//#define PROFILER_MAXSECTIONS 20
50//#define PROFILER_RESULTSFILE "test.prf"
51
52
53//check if we do actually want to profile?
54#ifndef PROFILER_ENABLE
55
56    // these defines ensure that all "calls" to the profiler-functions
57    // are ignored and a commentsign (//) is included, so that
58    // PROFILER_BEGINSECTION(1);   becomes   //(1);   which is harmless
59    #define PROFILER_START /##/
60    #define PROFILER_BEGINSECTION /##/
61    #define PROFILER_ENDSECTION /##/
62    #define PROFILER_STOP /##/
63
64#else // --- profiling enabled! -------------------------------
65
66    // check if user has set all options properly
67    #ifndef PROFILER_MAXSECTIONS
68        #error "PROFILER_MAXSECTIONS is undefined. Use  #define PROFILER_MAXSECTIONS <number>  to set the number of profile sections you're using!"
69    #endif
70
71    #ifndef PROFILER_RESULTSFILE
72        #error "PROFILER_RESULTSFILE is undefined. Use  #define PROFILER_RESULTSFILE ``sample.prf``  (with normal double-quotes) if your program is called ``sample.nxc``"
73    #endif
74
75
76    // global variables, these determine the memory usage!
77    long __PROFILER_GlobalStartTick;
78    long __PROFILER_ExecutionCount[PROFILER_MAXSECTIONS];
79    long __PROFILER_ElapsedTicks[PROFILER_MAXSECTIONS];
80    long __PROFILER_LastTick[PROFILER_MAXSECTIONS];
81    long __PROFILER_ExecutionsSameMs[PROFILER_MAXSECTIONS];
82
83
84    // init the whole profiling process!
85    inline void PROFILER_START() {
86        // not much to do, remember when we start.
87        DeleteFile(PROFILER_RESULTSFILE);
88        __PROFILER_GlobalStartTick = CurrentTick();
89    }//end void
90
91
92    // at the begin of every code section to be profiled, we have:
93    inline void PROFILER_BEGINSECTION(const int &no) {
94        // just remember timestamp
95        __PROFILER_LastTick[no] = CurrentTick();
96    }//end void
97   
98   
99    // at the end of every code section to be profiled, collect results:
100    inline void PROFILER_ENDSECTION(const int &no) {
101        // expensive function :-(
102       
103        // count the times this section has been executed
104        __PROFILER_ExecutionCount[no] =  __PROFILER_ExecutionCount[no] + 1;
105       
106        // record elapsed time (if possible)
107        if (CurrentTick() != __PROFILER_LastTick[no]) {
108            // count the number of times where no tick has happened
109            __PROFILER_ExecutionsSameMs[no] = __PROFILER_ExecutionsSameMs[no] + 1;
110        } else {
111            // add up the ticked milliseconds -- not the best way?
112            __PROFILER_ElapsedTicks[no] = __PROFILER_ElapsedTicks[no] + (CurrentTick() - __PROFILER_LastTick[no]);
113        }//end if
114    }//end void
115   
116   
117    // at the very end of each profiler session, calc results and store to file
118    inline void PROFILER_STOP() {
119   
120        // first calc total runtimes
121        long TotalRunTime    = CurrentTick() - FirstTick();
122        long ProfiledRunTime = CurrentTick() - __PROFILER_GlobalStartTick;
123
124        // calc max. filesize required...
125        long fileSize = 0;
126        fileSize = fileSize + 3 + 1 + 2;  // Firmware Version + Enhanced flag
127        fileSize = fileSize + 4 + 2;      // TotalRunTime
128        fileSize = fileSize + 4 + 2;      // ProfiledRunTime
129        fileSize = fileSize + 4 + 2;      // PROFILER_MAXSECTIONS
130        fileSize = PROFILER_MAXSECTIONS * (3 * 4 + 2); // profiler results + linebreak
131       
132        // needed to make everything clean etc.
133        string tmpStr1 = "";
134        string tmpStr2 = "";
135        string tmpStr3 = "";
136        string tmpStr4 = "";
137        long   tmpLong = 0;
138       
139        // prepare file...
140        long bytesWritten = 0;
141        byte fid = 0;
142        CreateFile(PROFILER_RESULTSFILE, fileSize, fid);
143
144        // start writing to file, line by line
145        // firmware version
146        tmpStr1 = NumToStr(__FIRMWARE_VERSION);
147        tmpStr2 = SubStr(tmpStr1, 0, 3);        // truncate to 3 chars if needed
148        #ifdef __ENHANCED_FIRMWARE
149            tmpStr1 = StrCat(tmpStr2, "1");     // enhanced
150        #else
151            tmpStr1 = StrCat(tmpStr2, "0");     // standard
152        #endif
153        WriteLnString(fid, tmpStr1, bytesWritten);
154       
155        // total run time
156        tmpStr1 = Flatten(TotalRunTime);
157        WriteLnString(fid, tmpStr1, bytesWritten);
158
159        // profiled run time
160        tmpStr1 = Flatten(ProfiledRunTime);
161        WriteLnString(fid, tmpStr1, bytesWritten);
162       
163        // PROFILER_MAXSECTIONS
164        tmpLong = PROFILER_MAXSECTIONS;
165        tmpStr1 = Flatten(tmpLong);
166        WriteLnString(fid, tmpStr1, bytesWritten);
167       
168        // now for every profile-section 1 line
169        for(int i = 0; i < PROFILER_MAXSECTIONS; i++) {
170       
171            // execution count, times no tick happened, elapsed ticks/ms
172            tmpStr1 = Flatten(__PROFILER_ExecutionCount[i]);
173            tmpStr2 = Flatten(__PROFILER_ExecutionsSameMs[i]);
174            tmpStr3 = Flatten(__PROFILER_ElapsedTicks[i]);
175            tmpStr4 = StrCat(tmpStr1, tmpStr2, tmpStr3);
176           
177            WriteLnString(fid, tmpStr4, bytesWritten);
178        }//end for
179
180        CloseFile(fid);
181
182    }//end void
183
184
185#endif
186
187
188
189
190
191
192// include empty main-task so we can check if this whole file compiles
193#ifdef __LOCAL_COMPILE_FAKE_TEST
194    task main(){
195
196    }//end task
197#endif
198
199
200
201#endif
202
Note: See TracBrowser for help on using the browser.