Trying to get the most out of RAM

I believe i am running into some ram issues with my chess code. Let me put this into perspective for you. There are 38 arrays, each with 120 integers in them. 12 of those arrays are look up tables. So i used PROGMEM on them so that they are stored in the flash memory and not transfered into ram. Many other integers too. But my program will not run with all of its functions.

The most i can get is 11 out of my 12 functions. Even more functions will be added. 

Basically i am trying to run all my functions:

all_moves_bknights();  // all these functions determine all the possible legal moves for a specific piece.

all_moves_brooks();

all_moves_bbishops();

etc.....

all_moves_wknights();

all_moves_wrooks();

etc.....

So the program works if i only have it call to the first 11 but when i try and call to all 12 then the program doesnt even run at all. Would this be a sign of a ram issue? Each function works individually too.  I wish i knew exactly how much ram i am using. The arduino mega has 8k of ram. 

How do you think i can save on ram? or is there no way to with such a large program? its going to be probably 50,000 bytes when done and i need to add even more functions that are probably more ram consuming than these, like calculating the best move. Should i get some slave arduinos?

 

calling the functions in sequence stops after the eleventh?

Some sort of limit is being vilated alright. Could you post one of them? I suppose, it does not really matter which one.

really long code below

 

 

I think this is against the rules?

 void all_moves_wbishops(){

       int rlm5;

  rlm5=0;

  int rrm5;

  rrm5=0;

   int inourway5=0;

   while(wbishopsmoves<121){

 int wbishopsread = Wbishops[wbishopsmoves];

  if(wbishopsread==2){

    bfx=11;

    while(bfx<=77){

  if(Wbishops[wbishopsmoves+bfx]==-1){

    rlm5=1;

  }

  if(rlm5==0){

    if(inourway5==0){

 if(Wbishops[wbishopsmoves+bfx] ==0){

   Wbishops_pos[wbishopsmoves+bfx]=1;  //here is a possible move for the bishop

   if(Wpieces[wbishopsmoves+bfx]==1){

    Wbishops_pos[wbishopsmoves+bfx]=0;

   inourway5=1; //did we land on one of our pieces? cant move there then

   }

   if(Bpieces[wbishopsmoves+bfx]==1){

   Wbishops_pos[wbishopsmoves+bfx]=1;

   inourway5=1; //did we land on a black piece? :smiley:

 }

  }

  }

  }

  bfx+=11;

    }

    bfx=11;

  inourway5=0;

  rlm5=0;

  while(bfx<=77){

    if(Wbishops[wbishopsmoves-bfx]==-1){

    rlm5=1;

  }

  if(rlm5==0){

    if(inourway5==0){

 if(Wbishops[wbishopsmoves-bfx] ==0){

   Wbishops_pos[wbishopsmoves-bfx]=1;  //here is a possible move for the bishop

   if(Wpieces[wbishopsmoves-bfx]==1){

    Wbishops_pos[wbishopsmoves-bfx]=0;

   inourway5=1; //did we land on one of our pieces? cant move there then

   }

   if(Bpieces[wbishopsmoves-bfx]==1){

   Wbishops_pos[wbishopsmoves-bfx]=1;

   inourway5=1; //did we land on a black piece? :smiley:

 }

  }

  }

  }

  bfx+=11;

  }

  bfx=13;

  inourway5=0;

  while(bfx<=91){

   if(Wbishops[wbishopsmoves+bfx]==-1){

    rrm5=1;

  }

  if(rrm5==0){

    if(inourway5==0){

 if(Wbishops[wbishopsmoves+bfx] ==0){

   Wbishops_pos[wbishopsmoves+bfx]=1;  //here is a possible move for the bishop

   if(Wpieces[wbishopsmoves+bfx]==1){

    Wbishops_pos[wbishopsmoves+bfx]=0;

   inourway5=1; //did we land on one of our pieces? cant move there then

   }

   if(Bpieces[wbishopsmoves+bfx]==1){

   Wbishops_pos[wbishopsmoves+bfx]=1;

   inourway5=1; //did we land on a black piece? :smiley:

 }

  }

  }

  }

  bfx+=13;

  }

  bfx=13;

  inourway5=0;

  rrm5=0;

  while(bfx<=91){

     if(Wbishops[wbishopsmoves-bfx]==-1){

    rrm5=1;

  }

  if(rrm5==0){

    if(inourway5==0){

 if(Wbishops[wbishopsmoves-bfx] ==0){

   Wbishops_pos[wbishopsmoves-bfx]=1;  //here is a possible move for the bishop

   if(Wpieces[wbishopsmoves-bfx]==1){

    Wbishops_pos[wbishopsmoves-bfx]=0;

   inourway5=1; //did we land on one of our pieces? cant move there then

   }

   if(Bpieces[wbishopsmoves-bfx]==1){

   Wbishops_pos[wbishopsmoves-bfx]=1;

   inourway5=1; //did we land on a black piece? :smiley:

 }

  }

  }

  }

  bfx+=13;

  }

  }

  //------------------------------------------------

    if(wbishopsread==4){

    bfx=11;

    while(bfx<=77){

  if(Wbishops[wbishopsmoves+bfx]==-1){

    rlm5=1;

  }

  if(rlm5==0){

    if(inourway5==0){

 if(Wbishops[wbishopsmoves+bfx] ==0){

   Wbishops_pos[wbishopsmoves+bfx]=3;  //here is a possible move for the bishop

   if(Wpieces[wbishopsmoves+bfx]==1){

    Wbishops_pos[wbishopsmoves+bfx]=0;

   inourway5=1; //did we land on one of our pieces? cant move there then

   }

   if(Bpieces[wbishopsmoves+bfx]==1){

   Wbishops_pos[wbishopsmoves+bfx]=3;

   inourway5=1; //did we land on a black piece? :smiley:

 }

  }

  }

  }

  bfx+=11;

    }

    bfx=11;

  inourway5=0;

  rlm5=0;

  while(bfx<=77){

    if(Wbishops[wbishopsmoves-bfx]==-1){

    rlm5=1;

  }

  if(rlm5==0){

    if(inourway5==0){

 if(Wbishops[wbishopsmoves-bfx] ==0){

   Wbishops_pos[wbishopsmoves-bfx]=3;  //here is a possible move for the bishop

   if(Wpieces[wbishopsmoves-bfx]==1){

    Wbishops_pos[wbishopsmoves-bfx]=0;

   inourway5=1; //did we land on one of our pieces? cant move there then

   }

   if(Bpieces[wbishopsmoves-bfx]==1){

   Wbishops_pos[wbishopsmoves-bfx]=3;

   inourway5=1; //did we black on a white piece? :smiley:

 }

  }

  }

  }

  bfx+=11;

  }

  bfx=13;

  inourway5=0;

  while(bfx<=91){

   if(Wbishops[wbishopsmoves+bfx]==-1){

    rrm5=1;

  }

  if(rrm5==0){

    if(inourway5==0){

 if(Wbishops[wbishopsmoves+bfx] ==0){

   Wbishops_pos[wbishopsmoves+bfx]=3;  //here is a possible move for the bishop

   if(Wpieces[wbishopsmoves+bfx]==1){

    Wbishops_pos[wbishopsmoves+bfx]=0;

   inourway5=1; //did we land on one of our pieces? cant move there then

   }

   if(Bpieces[wbishopsmoves+bfx]==1){

   Wbishops_pos[wbishopsmoves+bfx]=3;

   inourway5=1; //did we land on a black piece? :smiley:

 }

  }

  }

  }

  bfx+=13;

  }

  bfx=13;

  inourway5=0;

  rrm5=0;

  while(bfx<=91){

     if(Wbishops[wbishopsmoves-bfx]==-1){

    rrm5=1;

  }

  if(rrm5==0){

    if(inourway5==0){

 if(Wbishops[wbishopsmoves-bfx] ==0){

   Wbishops_pos[wbishopsmoves-bfx]=3;  //here is a possible move for the bishop

   if(Wpieces[wbishopsmoves-bfx]==1){

    Wbishops_pos[wbishopsmoves-bfx]=0;

   inourway5=1; //did we land on one of our pieces? cant move there then

   }

   if(Bpieces[wbishopsmoves-bfx]==1){

   Wbishops_pos[wbishopsmoves-bfx]=3;

   inourway5=1; //did we land on a black piece? :smiley:

 }

  }

  }

  }

  bfx+=13;

  }

  }

   wbishopsmoves++;

   }

   if(wbishopsmoves>121){

     wbishopsmoves=0;

  all_moves_wpawns(); // move on to next function

   }

 }

 

 

it says a way to calculate

it says a way to calculate ram is just add up all your bytes. i guess i am running at 26 arrays * 144 = 3744 *2 (integer is 2 bytes) = 7488. Plus some other stuff probably brings me over 8k. But 26 arrays + 11 functions works. But 26 arrays + 12 functions doesnt? Are the functions changing the ram? i do not think so because they are only changing numbers in the already setup arrays.

 

Are you function hopping?

At the very bottom of this all_moves_wbishops() you are calling all_moves_wpawns(). Do you call all the all_moves_XXX() functions from the previous function? Perhaps your chip or lingo does not like them nesting so deep.

That should be something you could find in the manual or experiment with.

Disclaimer: I do not really speak Arduino…

its possible. I am going to

its possible. I am going to try and make it all one function.

Might be stack overflow

Not sure about Arduino but by default in avr-gcc (not sure if Arduino even uses it but I think it does) stack is located in the end of SRAM and it’s growing downwards (see here: http://www.nongnu.org/avr-libc/user-manual/malloc.html). If you are using a lot of RAM for global arrays you may have stack overflow situation. For every function call at least the return address is pushed to the stack (and popped when returning). Avr-gcc will also push a couple of registers to stack even when there’s no argument passing to functions. So if your arrays are already filling up SRAM from “the bottom” your stack might hit the “top” of your arrays when it’s growing “downwards”.

I’m really tired now so I’m not so sure if I made any sense. May I should check this again tomorrow. Also, I haven’t done anything with Arduino. I hope it helps anyway :slight_smile:

 

Check out avr-size command too

Just remembered: If Arduino uses GNU toolchain (avr-gcc and stuff) there’s avr-size command you can use (on .elf and .o files). Just used it like this:
avr-size my-prog.elf

.data and .bss sections eat up your SRAM. Here’s more detailed explanation of those sections: http://www.nongnu.org/avr-libc/user-manual/mem_sections.html

Now I’m off to bed.

 

I found this, thought it

I found this, thought it might help…  http://www.nongnu.org/avr-libc/user-manual/pgmspace.html

EDIT: This might be more useful though…   http://www.arduino.cc/en/Reference/PROGMEM

EDIT2: just saw you tried that…Nevermind…  :confused:

With some code change, i am

With some code change, i am able to get rid of 10 arrays. So almost 3k of ram buy my calculations.

Trying to make your code

Trying to make your code more efficient is definitely the way to go, but if you reach the limits of how far you can optimise the program then I’d suggest taking a look into getting one or more external SRAM ICs. They’re designed for faster writes and higher endurance than EEPROM, and you can get a 256kb (32kB) SRAM IC for less than US$2 (SMD and PDIP packaging options available).

After looking at this code I

After looking at this code I think it’s possible to cut it down to 1/3 of what it currently is. There are several parts that are reused over and over again that can be put into their own functions and just have vars passed to those functions. You could also have flags for certain vars  as well…

One or twelve

Don’t do that. It will make the code harder to manage and read. Just call them one by one from the main loop. Without nesting.

i changed it. They are

i changed it. They are called individually during the function for figuring out the best move. No RAM issues now that i deleted 10 arrays.