Page 1 of 1

Macro local variable limit

Posted: Thu Dec 06, 2012 11:33 pm
by Mantas
Hello MM,

I was creating a macro an I encountered a limit of available macro local variables which is I believe 31. Why is there a limit, and how to remove it? Or does it need an update in software itself? :?

Best regards,
Mantas

Re: Macro local variable limit

Posted: Fri Dec 07, 2012 12:01 am
by Enamul
I was creating a macro an I encountered a limit of available macro local variables which is I believe 31.
Yes, you are right...the number is 31! Although I believe this number is big for local variable but obviously this is limited in the main software. Jonny might have few more thing to tell about this.

Re: Macro local variable limit

Posted: Fri Dec 07, 2012 12:44 am
by Mantas
Hey Enamul,

I was writing a macro and I have a list of 35 local variables, so 31 squeezed in, but 4 were left out, and its annoying, because it's all about order. Now some of the variables used in calculations are with prefix .(dot) and other four are without, cause i had to move the other 4 to global... :? I agree it is really rare to see so many locals in a macro, but here it is, I found one :) And 31 is a strange number as a limit...and why would you want to limit something like that, right? :shock:


Best regards,
Mantas

Re: Macro local variable limit

Posted: Fri Dec 07, 2012 1:08 am
by JonnyW
Hello. The limit is 32 - a nice round number (in hex!). Can I ask what you need to do to have 35 variables locally? If they are in order are they better suited in an array?

To answer your question yes - it requires a change in the executable.

In future versions we may remove the limit but this was originally added for speed mostly (fixed-size arrays are faster and easier than dynamic lists). I limited this to what I thought would be a large enough value in v5 (increased from something like 10 in v4).

I do not know your program so maybe that number of vars is necessary, but 35 is a lot (I don't think any function in the Flowcode executable has that many!) and may be an indication a bit of refactoring might be in order. Is it possible to break your macro into smaller chunks?

Cheers,

Jonny

Re: Macro local variable limit

Posted: Fri Dec 07, 2012 1:09 am
by Enamul
Yes..31 is a strange number (2^5-1). Jonny might say why that is 31 why not 128 or 256. I guess that could be linked with compilers ability and no of register in small PIC. Because in ASM these local variable are re-used in different macro..May be that's why limited :roll:
Sorry Jonny might have cross posted!!

Re: Macro local variable limit

Posted: Fri Dec 07, 2012 1:43 am
by Mantas
Hello Jonny,

Yes I agree, it strange, but it only to improve macros speed, so I use auxiliary variables to avoid repeated arithmetic. I am doing a code for MARG, so all calculations are for quaternion. Quite a lot of math ops so even after reduction using aux var it still is 277 math ops with floats. I will show you a part of macro for the aux vars. Maybe storing them in an array is a good Idea, i will try it, but it can make me a lot of confusion.

Code: Select all

// Auxiliary variables to avoid repeated arithmetic
._2q0mx = 2.0 * q0 * .mx
._2q0my = 2.0 * q0 * .my
._2q0mz = 2.0 * q0 * .mz
._2q1mx = 2.0 * q1 * .mx
._2q0 = 2.0 * q0
._2q1 = 2.0 * q1
._2q2 = 2.0 * q2
._2q3 = 2.0 * q3
._2q0q2 = 2.0 * q0 * q2
._2q2q3 = 2.0 * q2 * q3
.q0q0 = q0 * q0
.q0q1 = q0 * q1
.q0q2 = q0 * q2
.q0q3 = q0 * q3
.q1q1 = q1 * q1
.q1q2 = q1 * q2
q1q3 = q1 * q3 //Global vars starts here
q2q2 = q2 * q2
q2q3 = q2 * q3
q3q3 = q3 * q3
And this is where all the magic happens:

Code: Select all

// Gradient decent algorithm corrective step
.s0 = - ._2q2 * (2.0 * q1q3 - ._2q0q2 - .ax) + ._2q1 * (2.0 * .q0q1 + ._2q2q3 - .ay) - ._2bz * q2 * (._2bx * (0.5 - q2q2 - q3q3) + ._2bz * (q1q3 - .q0q2) - .mx) + (- ._2bx * q3 + ._2bz * q1) * (._2bx * (.q1q2 - .q0q3) + ._2bz * (.q0q1 + q2q3) - .my) + ._2bx * q2 * (._2bx * (.q0q2 + q1q3) + ._2bz * (0.5 - .q1q1 - q2q2) - .mz)
.s1 = ._2q3 * (2.0 * q1q3 - ._2q0q2 - .ax) + ._2q0 * (2.0 * .q0q1 + ._2q2q3 - .ay) - 4.0 * q1 * (1 - 2.0 * .q1q1 - 2.0 * q2q2 - .az) + ._2bz * q3 * (._2bx * (0.5 - q2q2 - q3q3) + ._2bz * (q1q3 - .q0q2) - .mx) + (._2bx * q2 + ._2bz * q0) * (._2bx * (.q1q2 - .q0q3) + ._2bz * (.q0q1 + q2q3) - .my) + (._2bx * q3 - ._4bz * q1) * (._2bx * (.q0q2 + q1q3) + ._2bz * (0.5 - .q1q1 - q2q2) - .mz)
.s2 = - ._2q0 * (2.0 * q1q3 - ._2q0q2 - .ax) + ._2q3 * (2.0 * .q0q1 + ._2q2q3 - .ay) - 4.0 * q2 * (1 - 2.0 * .q1q1 - 2.0 * q2q2 - .az) + (- ._4bx * q2 - ._2bz * q0) * (._2bx * (0.5 - q2q2 - q3q3) + ._2bz * (q1q3 - .q0q2) - .mx) + (._2bx * q1 + ._2bz * q3) * (._2bx * (.q1q2 - .q0q3) + ._2bz * (.q0q1 + q2q3) - .my) + (._2bx * q0 - ._4bz * q2) * (._2bx * (.q0q2 + q1q3) + ._2bz * (0.5 - .q1q1 - q2q2) - .mz)
.s3 = ._2q1 * (2.0 * q1q3 - ._2q0q2 - .ax) + ._2q2 * (2.0 * .q0q1 + ._2q2q3 - .ay) + (- ._4bx * q3 + ._2bz * q1) * (._2bx * (0.5 - q2q2 - q3q3) + ._2bz * (q1q3 - .q0q2) - .mx) + (- ._2bx * q0 + ._2bz * q2) * (._2bx * (.q1q2 - .q0q3) + ._2bz * (.q0q1 + q2q3) - .my) + ._2bx * q1 * (._2bx * (.q0q2 + q1q3) + ._2bz * (0.5 - .q1q1 - q2q2) - .mz)
By the way, I don't remember if it was mentioned earlier, but I found that sqrt() function is missing in the flowcode, so I had to use pow(float,0.5) instead.

Best regards,
Mantas

Re: Macro local variable limit

Posted: Fri Dec 07, 2012 1:54 am
by JonnyW
Hi. Its to do with memory and speed on the PC, as it goes. Each Flowchart and sub-flowchart that is created contains that number of variables in an array. This means we would have to create, say, 256 variables for every flowchart just on the off chance they are needed. This seems extreme for 99.9% of cases - its just a shame we have found the remaining 0.1% ! Maybe for later versions I will make this number dynamic and unlimited.

For quaternions and matrix multiplication I tend to use arrays - it makes life easier as you can easily loop through the elements but then ideally for this (looking at your code) you could do with a 2d array, which Flowcode does not support (yet).

Unless you are passing into a function, perhaps you could break these into 4d vectors - for example _2q = 2 * {q0, q1, q2, q3}. Eg: _2q[0] = 2 * q0

Also as a quick optimisation to cut down on muls above, if you move _2q0mx, _2q0my, _2q0mz below _2q0 you can use this instead of (2.0 * q0).

EDIT: I'll look into the sqrt function missing.

Cheers,

Jonny

Re: Macro local variable limit

Posted: Fri Dec 07, 2012 2:06 am
by Mantas
As you probably know, but to be clear I use ARM v5.

Your suggestion to use the array is really good, I will try to do it tomorrow, or is it already today...heh time to go to bed...its not healthy to do quaternion calcs after the midnight :D

Best regards,
Mantas