Need help with efficiency NXC code
Need help with efficiency NXC code
Hi,
I need some help with some code I have. It runs a little slow and I am trying to make it run faster.
It has lots of &&'s and ||'s all mixed up which probably cause part of the lagging.
I would just need help overall, especially the for-loop in the "mGameTask.nxc"
I would greatly appreciate some help.
Thanks,
nxtboy III
I need some help with some code I have. It runs a little slow and I am trying to make it run faster.
It has lots of &&'s and ||'s all mixed up which probably cause part of the lagging.
I would just need help overall, especially the for-loop in the "mGameTask.nxc"
I would greatly appreciate some help.
Thanks,
nxtboy III
- Attachments
-
- NXC Code.zip
- (12.19 KiB) Downloaded 410 times
Thanks, and have a nice day,
nxtboy III
programnxt.com
nxtboy III
programnxt.com
Re: Need help with efficiency NXC code
The first thing in optimizing code is always measuring: Find out where it runs slowly. It's often not where you think. Old rule:
Unfortunately the NXTasy post with a sort-of manual is gone, but you could basically do something like this. In your task Game:
As you can see, I added some #define, an #include, and then the profiler-commands. All you have to make sure is, that somewhere in that file, PROFILER_START() gets called once before the other profiler commands. At the end, somewhere, you have to call PROFILER_STOP() once, too. Otherwise it won't work. I'm not sure if I chose the right position in your code...
The main thing is then to mark sections that should be profiled. Set how many sections you have at max with
in the beginning.
Then you have to manually wrap every line or section of code with PROFILER_BEGINSECTION(n) and PROFILER_ENDSECTION(n), where n is a constant integer expression. I think you don't have to have the sections "in order", but it's all an early alpha version, so better do that. You should also make sure that both commands are in the same scoping level, i.e. you begin and end a section within the same "code flow" (for example, avoid having an end-section outside some if-statement that is not reached as often as the begin-section).
That should be it. You should run the program and stop it gracefully (so that PROFILER_STOP() gets executed). You should then find a file called "game.prf" on your NXT. Copy it to your computer, and run the Python script to generate a highlighted HTML version of your code. If you can't get it to work, send me the .prf file, and I'll do it.
You can of course wrap the stuff you marked with //*************** in your code in between profiler sections, I just didn't do it to save code space here.
You have to download Profiler01.nxc and put it to your projects directory, here is a direct download link: http://www.mindstorms.rwth-aachen.de/tr ... iler01.nxc
The profiled program might run slower (up to a factor of 2 to 10), this is normal. You can leave in all the profiler commands and just not #define PROFILER_ENABLE. If you do this, all profiler-commands evaluate to empty macros and should have no effects at all.
More things and an example is described on the project page I linked above. Sorry if this kind of hijacked your thread, but I can think together with the NXC-experts here it could seriously help speed up you program -- once we know where it's slow
Edit: I should note this whole stuff only works for ONE NXC file at the moment. And I guess all profiler section commands should be in one single task. This is all given for your game task.
I'm not only posting this because it's true, but also because I'd be really happy if you were willing to give my NXC Profiler a spin: http://www.mindstorms.rwth-aachen.de/tr ... XCProfilerMeasure twice, optimize once.
Unfortunately the NXTasy post with a sort-of manual is gone, but you could basically do something like this. In your task Game:
Code: Select all
// SET UP THE PROFILER
// comment this out to silently disable profiling without any side effects!
#define PROFILER_ENABLE
// how many times did we use PROFILER_BEGINSECTION (and ENDSECTION)
#define PROFILER_MAXSECTIONS 7
// name of the binary results file we later analyze
#define PROFILER_RESULTSFILE "game.prf"
// this does all the magic :-)
#include "Profiler01.nxc"
task Game()
{
PROFILER_START();
while(1)
{
while(play == 1)
{
paddx=fmapx == floor(fmapx)?0:1;
if(SENSOR_2 && SENSOR_1)
{
StopAllTasks();
}
ShootFireBall();
Jump();
mapy=floor(fmapy);
mapx=floor(fmapx);
paddy=fmapy == floor(fmapy)?0:1;
paddx=fmapx == floor(fmapx)?0:1;
MoveLeft();
mapy=floor(fmapy);
mapx=floor(fmapx);
if(fmapy == floor(fmapy))
{
paddy=0;
}
else
{
paddy=1;
}
PROFILER_BEGINSECTION(0);
MoveRight();
PROFILER_ENDSECTION(0);
mapy=floor(fmapy);
mapx=floor(fmapx);
paddx=fmapx == floor(fmapx)?0:1;
if(!ButtonPressed(BTNCENTER,0) && jc != 0)
{
ffd=1;
jumping=0;
}
PROFILER_BEGINSECTION(1);
FireBallHit();
PROFILER_ENDSECTION(1);
PROFILER_BEGINSECTION(2);
Down();
PROFILER_ENDSECTION(2);
s=0;
mapy=floor(fmapy);
mapx=floor(fmapx);
CheckVargs();
Tile();
CheckFireBall();
fballx+=xpp;
fbally+=ypp;
//********************************************************************************************************************
// [snipped]
//********************************************************************************************************************
// [snipped]
}
PlayToneEx(600,30,1,0);
PROFILER_STOP();
}
}
The main thing is then to mark sections that should be profiled. Set how many sections you have at max with
Code: Select all
#define PROFILER_MAXSECTIONS 7
Then you have to manually wrap every line or section of code with PROFILER_BEGINSECTION(n) and PROFILER_ENDSECTION(n), where n is a constant integer expression. I think you don't have to have the sections "in order", but it's all an early alpha version, so better do that. You should also make sure that both commands are in the same scoping level, i.e. you begin and end a section within the same "code flow" (for example, avoid having an end-section outside some if-statement that is not reached as often as the begin-section).
That should be it. You should run the program and stop it gracefully (so that PROFILER_STOP() gets executed). You should then find a file called "game.prf" on your NXT. Copy it to your computer, and run the Python script to generate a highlighted HTML version of your code. If you can't get it to work, send me the .prf file, and I'll do it.
You can of course wrap the stuff you marked with //*************** in your code in between profiler sections, I just didn't do it to save code space here.
You have to download Profiler01.nxc and put it to your projects directory, here is a direct download link: http://www.mindstorms.rwth-aachen.de/tr ... iler01.nxc
The profiled program might run slower (up to a factor of 2 to 10), this is normal. You can leave in all the profiler commands and just not #define PROFILER_ENABLE. If you do this, all profiler-commands evaluate to empty macros and should have no effects at all.
More things and an example is described on the project page I linked above. Sorry if this kind of hijacked your thread, but I can think together with the NXC-experts here it could seriously help speed up you program -- once we know where it's slow
Edit: I should note this whole stuff only works for ONE NXC file at the moment. And I guess all profiler section commands should be in one single task. This is all given for your game task.
RWTH - Mindstorms NXT Toolbox for MATLAB
state of the art in nxt remote control programming
http://www.mindstorms.rwth-aachen.de
MotorControl now also in Python, .net, and Mathematica
state of the art in nxt remote control programming
http://www.mindstorms.rwth-aachen.de
MotorControl now also in Python, .net, and Mathematica
Re: Need help with efficiency NXC code
That is very neat! Unfortunately, I do not have a Python compiler. How would I actually speed up the program?
Thanks
Thanks
Thanks, and have a nice day,
nxtboy III
programnxt.com
nxtboy III
programnxt.com
Re: Need help with efficiency NXC code
Python is free and open source, you just need an interpreter, 1 installer. You'd usually grab the appropriate version from here http://www.python.org/download/releases/2.7.2/ (for windows, the correct x86 or x64 MSI installer).nxtboyiii wrote:That is very neat! Unfortunately, I do not have a Python compiler.
After that, you would open a command prompt on your computer and run
Code: Select all
python AnalyzeNXCProfile.py -p game.prf -s mGameTask.nxc -o game.html -v
The game.prf is generated on your NXT by the profiled version of your program.
But you don't have to do this. If you send me the game.prf and the exact version of mGameTask.nxc that created it, I could generated the HTML file for you.
Well, the actual optimization comes after that of course. But profiling gives a clou at WHERE to optimize and do the speed ups. Right now, you say your program is slow between the parts you marked with //************** . Did you measure that, or is it just a feeling?nxtboyiii wrote: How would I actually speed up the program?
Anyway, I didn't give you a single optimization hint for NXC in this thread yet, sorry. If anyone else wants to go ahead and help, please do so. I just saw the opportunity for a useful "real life test" of the profiler. The results might confirm what you say, that your program is slow between the **** parts, or it might show that your program is slow somewhere else...
You know, there's usually some kind of 90-10 rule for each computer program, which says that "90% of the execution time is spent in 10% of the code". Our goal is now to find that 10%.
RWTH - Mindstorms NXT Toolbox for MATLAB
state of the art in nxt remote control programming
http://www.mindstorms.rwth-aachen.de
MotorControl now also in Python, .net, and Mathematica
state of the art in nxt remote control programming
http://www.mindstorms.rwth-aachen.de
MotorControl now also in Python, .net, and Mathematica
Re: Need help with efficiency NXC code
Well, I know that if I sped that part up(with the //****) then it would go faster.
You see, when there are more enemies, it goes slower because it has to process more enemies. If I make that part faster, then when there are more enemies it won't slow down as much and won't make a huge difference.
I could probably generate and send the game.prf file tomorrow, maybe.
Thanks
You see, when there are more enemies, it goes slower because it has to process more enemies. If I make that part faster, then when there are more enemies it won't slow down as much and won't make a huge difference.
I could probably generate and send the game.prf file tomorrow, maybe.
Thanks
Thanks, and have a nice day,
nxtboy III
programnxt.com
nxtboy III
programnxt.com
Re: Need help with efficiency NXC code
Ok, but no pressure or anything. Just if you feel like it, whenever. Otherwise never mind.nxtboyiii wrote:I could probably generate and send the game.prf file tomorrow, maybe.
You still would have to place the profiler sections at "interesting parts", where you feel the program might be slow or where you want to know how often / how fast parts get executed. Oe more thing: nested sections are not allowed! I.e. not this:
Code: Select all
PROFILER_BEGINSECTION(0);
// code...
PROFILER_BEGINSECTION(1);
// code...
PROFILER_ENDSECTION(1);
// code...
PROFILER_ENDSECTION(0);
nxtboyiii wrote:Well, I know that if I sped that part up(with the //****) then it would go faster.
You see, when there are more enemies, it goes slower because it has to process more enemies. If I make that part faster, then when there are more enemies it won't slow down as much and won't make a huge difference.
I looked a bit at that code, and there are two general principles you can apply:
1. In your big if-clauses, make assumptions about the conditions and sort them cleverly. I.e. take
Code: Select all
if(fmapy == floor(fmapy) && (E.eat == 3 || E.eat == 7) && (mapx == E.mex || mapx+paddx == E.mex || mapx == E.mex+E.pex || mapx+paddx == E.mex+E.pex) && jumped == 0)
Code: Select all
if (likelyThing && unlikelyThing) {
// code ...
Code: Select all
if (unlikelyThing && likelyThing ) {
// code ...
The other thing is with ||:
Code: Select all
if (unlikelyThing || likelyThing ) {
// code ...
Code: Select all
if (likelyThing || unlikelyThing) {
// code ...
RWTH - Mindstorms NXT Toolbox for MATLAB
state of the art in nxt remote control programming
http://www.mindstorms.rwth-aachen.de
MotorControl now also in Python, .net, and Mathematica
state of the art in nxt remote control programming
http://www.mindstorms.rwth-aachen.de
MotorControl now also in Python, .net, and Mathematica
Re: Need help with efficiency NXC code
2. The other general thing is: "Precache" as much as possible. Array-access (lookup) is very expensive in NXC (same ballpark as math operations). So, I noticed you frequently use things like
If you know which of these array elements get used more than once (I suspect most of them do), create local variables at the begin of your loop:
and so on (I think you get the principle: I encoded the -1 as index 0, the index "+0" as 1, and +1 as 2, and just put x, then y in the variable name). Then use these vars instead of the array.
Just a side note: In C++ (and maybe C, but I don't know C that much), it's a good habit to use
With this consts vars (or const references), the compiler might be more likely to do optimizations.
Anyway, you'd have to cleverly analyze your code, and only do the array-precache-lookup, if you know you're probably losing it. I didn't check your code so good, but if for example, in your first if-clause, you check if an enemy is dead (and exit/break in case he is), then do this array lookup only if your still "in" that loop, not before. The lookups are expensive, too. And if you do them too often or too early, you might deteriorate performance.
This is why it's so important to measure execution speed. You have to know and verify whether your optimization made any sense. Do you have a FPS / frame counter in your game?
A simple timer around your enemy-loop might be enough to at least show the milliseconds it took. The profiler-sections are just some sort of automated glorified timers, which also calc the average execution time...
Code: Select all
(map[E.mex-1][E.mey].sld >= 1 || map[E.mex+1][E.mey].sld >= 1)
Code: Select all
int map_sld_01 =[E.mex-1][E.mey].sld;
int map_sld_11 =[E.mex][E.mey].sld;
int map_sld_21 =[E.mex+1][E.mey].sld;
Just a side note: In C++ (and maybe C, but I don't know C that much), it's a good habit to use
Code: Select all
const int map_sld_01 = ...;
// or, depending on context,
// const int & rMap_sld_01 = ...; // this is a const reference
Anyway, you'd have to cleverly analyze your code, and only do the array-precache-lookup, if you know you're probably losing it. I didn't check your code so good, but if for example, in your first if-clause, you check if an enemy is dead (and exit/break in case he is), then do this array lookup only if your still "in" that loop, not before. The lookups are expensive, too. And if you do them too often or too early, you might deteriorate performance.
This is why it's so important to measure execution speed. You have to know and verify whether your optimization made any sense. Do you have a FPS / frame counter in your game?
A simple timer around your enemy-loop might be enough to at least show the milliseconds it took. The profiler-sections are just some sort of automated glorified timers, which also calc the average execution time...
RWTH - Mindstorms NXT Toolbox for MATLAB
state of the art in nxt remote control programming
http://www.mindstorms.rwth-aachen.de
MotorControl now also in Python, .net, and Mathematica
state of the art in nxt remote control programming
http://www.mindstorms.rwth-aachen.de
MotorControl now also in Python, .net, and Mathematica
Re: Need help with efficiency NXC code
Thanks! That helps a lot.
But the E.mex and E.mey change during the loop(I should probably change the variable names to make them more understandable).If you know which of these array elements get used more than once (I suspect most of them do), create local variables at the begin of your loop:
int map_sld_01 =[E.mex-1][E.mey].sld;
int map_sld_11 =[E.mex][E.mey].sld;
int map_sld_21 =[E.mex+1][E.mey].sld;
Thanks, and have a nice day,
nxtboy III
programnxt.com
nxtboy III
programnxt.com
Re: Need help with efficiency NXC code
@Linus Is this your NXTasy post?
Commit to LEGO Mindstorms Robotics Stack Exchange:
bit.ly/MindstormsSE
Commit to LEGO Stack Exchange: bit.ly/Area51LEGOcommit
Re: Need help with efficiency NXC code
Thanks, good I saved that part. But no, I believe in that post, there was moremuntoo wrote:@Linus Is this your NXTasy post?
Anyway, muntoo, don't you have some performance-intense code or some NXC-OpenGL-like stuff or a game or whatever where you'd want to try the NXC Profiler? I'd love to see a real-life testcase, but I'm without an NXT (for a long time already).
RWTH - Mindstorms NXT Toolbox for MATLAB
state of the art in nxt remote control programming
http://www.mindstorms.rwth-aachen.de
MotorControl now also in Python, .net, and Mathematica
state of the art in nxt remote control programming
http://www.mindstorms.rwth-aachen.de
MotorControl now also in Python, .net, and Mathematica
Who is online
Users browsing this forum: No registered users and 4 guests