I am trying to use an array in my code, which is uint_8 and [512][5] in size. Seems like I am running out of space on my MEGA. So I tried using link list which does give me space but runs very slowly. So I was thinking if there is any other healthy alternative to using array. Prior to all this I was using recursion which was also talking up memory so I switched to iteration which again takes up memory.
Your problem seems to need more than 8k RAM,
or your attempt at solving it needs more.
If only for processing power and RAM, I would suggest using an ESP32 based system.
I don't see any code.
Not if you dynamically create 512 items of 5 bytes. If you need 512*5 bytes, you need 512*5 bytes, no discussion possible. The only point is that the IDE does not report on dynamically allocated memory and you probably fell for that.
StackArray<uint8_t> deadi;
StackArray<uint8_t> deadj;
StackArray<uint8_t> floodx;
StackArray<uint8_t> floody;
StackArray<uint16_t> floodn;
StackArray<uint8_t> floodadd;
StackArray<uint8_t> floodlast;
StackArray<uint8_t> floodstate;
This what i tried to do instead of array, because i dont need 512*5 bytes all the time, i just need it in a function which uses it, at other time i want to deallocate it. The problem is that other functions which dont need these also need memory and thus they are running out of memory because memory is already allocated to the array.
So at a a point in time you need 2.5KB of SRAM for this array, on top of what you already use elsewhere. if that gets you over the max SRAM available you are toast. So the question is what does the rest of the code do, how much SRAM does it need?
around 4k
You can jump high and low but that will require 512*5 bytes at the moment that the function is called. So if the IDE reports, as an example, 6k use (2k available) and you add your 2.5k dynamically allocated memory to it you have a problem.
if that's what the compiler reports, it's only the statically allocated memory. Do you have other parts of the code where functions would also allocate memory ? String objects, dynamic memory allocation, passing big objects by value etc...
Given that you need this memory even transiently, you could try allocating it statically so that it's always reserved and see what the compiler reports.
if you can post the code, we could have a look
Suppose i have a controller function main which calls func a and b
void main()
{ a();b();}
Now a needs 512x5 bytes but once its work is over, b is called which doesnt need 512x5 bytes. But since i am declaring the array as global this happens. Ok now, i think initializing the array as local will work. But is that really efficient to allocate arrays locally? Will the get deleted after func call is over? Or will the remain in the memory?
A better question might be what the actual code is. The last snippet that I did see
If that runs 512 recursions, OP can add a minimum of 512x2 bytes to the 4k usage. And probably a few more per iteration.
I have replaced all string with linked list, so its not a problem anymore, i dont pass big objects, all big objects are declared global and can be accessed. And all i pass is uint_8 values. The linked list does allocate dynamically but thats not a problem because there size is small and i delete them immediately.
This is the last code i wrote, now i am using this
void refill_set(uint8_t i, uint8_t j, uint16_t num) {
floodx.push(i);
floody.push(j);
floodn.push(num);
while (!floodx.isEmpty()) {
uint8_t x = floodx.pop();
uint8_t y = floody.pop();
uint16_t n = floodn.pop();
if (flood[x][y] == 512 && ((x == box / 2 || x == box / 2 - 1) && (y == box / 2 || y == box / 2 - 1))) {
n = 0;
} else if (flood[x][y] <= n) {
continue;
}
// log(""+x+" "+y);
flood[x][y] = n;
n++;
if ((global[x][y] | 7) != 15 && flood[x - 1][y] > n) {
floodx.push((x - 1));
floody.push(y);
floodn.push(n);
}
if ((global[x][y] | 11) != 15 && flood[x][y + 1] > n) {
floodx.push(x);
floody.push((y + 1));
floodn.push(n);
}
if ((global[x][y] | 13) != 15 && flood[x + 1][y] > n) {
floodx.push((x + 1));
floody.push(y);
floodn.push(n);
}
if ((global[x][y] | 14) != 15 && flood[x][y - 1] > n) {
floodx.push(x);
floody.push((y - 1));
floodn.push(n);
}
}
}
void refill_set_rev(uint8_t i, uint8_t j, uint16_t num) {
floodx.push(i);
floody.push(j);
floodn.push(num);
while (!floodx.isEmpty()) {
uint8_t x = floodx.pop();
uint8_t y = floody.pop();
uint16_t n = floodn.pop();
if (flood[x][y] <= n) {
continue;
}
// log(""+x+" "+y);
flood[x][y] = n;
n++;
if ((global[x][y] | 7) != 15 && flood[x - 1][y] > n) {
floodx.push((x - 1));
floody.push(y);
floodn.push(n);
}
if ((global[x][y] | 11) != 15 && flood[x][y + 1] > n) {
floodx.push(x);
floody.push((y + 1));
floodn.push(n);
}
if ((global[x][y] | 13) != 15 && flood[x + 1][y] > n) {
floodx.push((x + 1));
floody.push(y);
floodn.push(n);
}
if ((global[x][y] | 14) != 15 && flood[x][y - 1] > n) {
floodx.push(x);
floody.push((y - 1));
floodn.push(n);
}
}
}
If you allocate dynamically you will have to delete it your self.
Why don't you post your full code so we can see what you're doing?
just out of curiosity - why do you think that's the issue?
if you actually see a performance issue and not a crash?
an arduino MEGA is slow compared to your PC. if what you do is complex, highly iterative, it will take time at 16MHz.
Because when the refill is called its supposed to do the flood fill, but at some point instead of doing that it resents all value of flood[][] to 0.
This occured when i used recursion, but after i used linked list, it did not get stuck initially but after some more time time it again did this
which ones do you use ?
Consider FRAM, it is not as fast as RAM but a lot faster then the alternatives. 32K x 8 not very expensive. I got a bunch of modules from china and have had no problems. They read and write like EEPROM but no delays and the write is instant byte by byte.
Both
Actually I have much more to add so I am thinking of i can't make this fast, what I am going to add wil make it even slower. I have planned on using esp32 I am Just seeing what more optimization I can do on my code