Let's Make Robots!

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?

 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

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).

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

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 :-)

 

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.

 

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 try and make it all one function.

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 called individually during the function for figuring out the best move. No RAM issues now that i deleted 10 arrays.

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

 

 

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? :D

 }

  }

  }

  }

  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? :D

 }

  }

  }

  }

  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? :D

 }

  }

  }

  }

  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? :D

 }

  }

  }

  }

  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? :D

 }

  }

  }

  }

  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? :D

 }

  }

  }

  }

  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? :D

 }

  }

  }

  }

  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? :D

 }

  }

  }

  }

  bfx+=13;

  }

  }

   wbishopsmoves++;

   }

   if(wbishopsmoves>121){

     wbishopsmoves=0;

  all_moves_wpawns(); // move on to next function

   }

 }