@spillerrec Of course, it's illegal for any function to call
main()
, according to the C++ standard.P.S. @linusa You've got competition.
main()
, according to the C++ standard.Thanks so much, I uploaded the profiled source code: http://linus.saydoo.com/mGameTask.htmlmuntoo wrote:Modified NXC files with the .prf file in the source directory. (I didn't have my NXT for a while, so it took a while.)
YEAH!!! Rock on. Really cool . Hope you put a blog post and/or manual + description. I browsed your source but not long, so I couldn't be bothered to work out what your "HISTORY" does and if it's basically the same concept I used. Are there key differences to my concept?muntoo wrote: P.S. @linusa You've got competition.
I've no clue about yours (I haven't looked at yours much either ), butlinusa wrote:what your "HISTORY" does and if it's basically the same concept I used. Are there key differences to my concept?
HISTORY
will (once I get it working) record previous TIMER
states. Basically:
Code: Select all
ENDSECTION
{
PUSH TIMER onto HISTORY
}
TOTAL
"works"..PRF
file format look like? Do you store the name of the profiled file/etc? Currently, mine's just HEADER={file_format, size of TOTAL/HISTORY}
and DATA={TOTAL, HISTORY}
.Code: Select all
PROFILER_BEGINSECTION(7);
Tile();
PROFILER_ENDSECTION(7);
Code: Select all
PROFILER_BEGINSECTION(11);
if (E.eat != 8)
EMYMoveDown(E);
PROFILER_ENDSECTION(11);
This tells us, that in 5% of the calls, this section was executed really quickly. In this case it probably means that> 2.8 ms (in 94%)
< 1.0 ms (in 5%)
(E.eat == 8)
was true 5% of the cases (could be useful to make estimates where to optimize).(play == 1)
section... (play == 1)
part. That way one has an estimate how fast this part is, and can compare after modifactions.I store Firmware Version, Enhanced flag, TotalRunTime, ProfiledRunTime (sum of execution time inside all sections), and then PROFILER_MAXSECTIONS. After that there are PROFILER_MAXSECTIONS "data entries", with 3 longs for each section: ExecutionCount, ExecutionsSameMs (number executions of a section where the firmware "didn't tick"), ElapsedTicks (sum of execution time of this section).muntoo wrote: How does your.PRF
file format look like? Do you store the name of the profiled file/etc? Currently, mine's justHEADER={file_format, size of TOTAL/HISTORY}
andDATA={TOTAL, HISTORY}
.
That depends on what you mean by it. If the whole game, then have a look at Tile() in mTileCheck.nxc and profile/analyze that. If you want that ******* part, then I'd do 2 things:nxtboyiii wrote:So how exactly do I optimize it?
Code: Select all
if(A.sc == 'D' || map[A.mex][A.mey-1].sld == 0)
{
if(A.sc == 'D' || (map[A.mex+A.pex][A.mey-1].sld == 0 && A.sc == 'N' && (A.eat != -2 || (A.eat == -2 && A.U == 0))))
{
Code: Select all
bool executeMe = false;
if(A.sc == 'D') {
executeMe = true;
} else if(map[A.mex][A.mey-1].sld == 0) {
executeMe = true;
} else if(A.sc == 'N') {
if (A.eat != -2 || (A.eat == -2 && A.U == 0)) {
if (map[A.mex+A.pex][A.mey-1].sld == 0) {
executeMe = true;
}//end if
}//end if
}//end if
// now the old inner part becomes
if (executeMe)
{
A.mc=0;
if(A.eat != -2 && A.eat != 4)
//...
A.mc=0; // etc...
part is actually executed.A.sc == 'D'
too often, you check A.eat != -2
more than once -- there's got to be a better logical way. But, I can't (don't want to) help in here, as this requires knowledge of your whole game. Start using CONSTANTS pr #defines for your magic values. If it says A.eat != ENEMY_EATING
instead of -2, you and others reading your code will at once know what it means. And this in turn makes optimizing easier...Does it run faster?nxtboyiii wrote:Wow, thanks! That helps a lot.(I changed some of the numbers to constants to make it easier to understand)
There is some confusion here. NXC has always had short circuit evaluation of && and || in boolean expressions. The thing that I was doing that I did not need to do was pushing the primary register onto the stack after the LHS and then popping it off the stack after the RHS (if the evaluation was not short circuited) and ANDing or ORing the two sides. Since I was already short circuiting the expression evaluation I didn't need to do the pushPrim or the popAnd/popOr bits. Spillerec also wanted me to ignore the boolean expression's value (0 or 1) but that is not generally safe since the boolean expression's 0 or 1 value can be used in comparisons, bitwise operations, math ops of any kind, or in assignments. Handling all of these possibilities correctly in any way other than always storing the value (0 or 1) in the primary register is non-trivial or maybe even impossible.linusa wrote: in boolean expressions with &&, apparently all things ARE evaluated in NXC at the moment. So I followed spillers advice and added more ifs to exit that branch as fast as possible.
Users browsing this forum: No registered users and 2 guests