Problem with code generated too big in 0.30.1 vs 0.29.1

Testing my example cesars/0-all-examples/0003-rich-time-schrolling v0.0.14 in version 0.30.1, the first thing I found is the lack of pulse-on-change, I solved it by changing to pulse-on-change(number).

Now in version 0.30.1 I have an error due to code too large, of 71% to 100%. (Arduino UNO)

Sketch uses 32368 bytes (100%) of program storage space. Maximum is 32256 bytes.
Global variables use 1958 bytes (95%) of dynamic memory, leaving 90 bytes for local variables. Maximum is 2048 bytes.
Sketch too big; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing it.

testing in 0.29.1

Sketch uses 23188 bytes (71%) of program storage space. Maximum is 32256 bytes.
Global variables use 1982 bytes (96%) of dynamic memory, leaving 66 bytes for local variables. Maximum is 2048 bytes.
Low memory available, stability problems may occur.
2 Likes

After editing some nodes, I managed to reduce the code

v0.30.1

of  100% to 83% of program storage space.
of  95% to 86%  of dynamic memory.

vs v0.29.1

of 71%  to 64% of program storage space. 
of 96% to 91% of dynamic memory.

I have only passed some nodes to C ++, in version 0.30.1 there has been more noticeable resource savings.

then I will upload the library update, version v0.0.16 or higher

1 Like

I’ve compared the generated C++ before and after 0.30. And yes, the problem is in the errors. Previously, they were ignored just in the place where they were emitted (the ERR pulse) and now every recursively downstream node makes a computation to check whether it is affected by an error or not. The deeper the node, the more complex the computation is:

        bool error_input_IDX = false;
        error_input_IDX |= node_102.outputHasError_BYTE;
        error_input_IDX |= node_97.outputHasError_DONE;
        error_input_IDX |= node_92.outputHasError_DONE;
        error_input_IDX |= node_86.outputHasError_DONE;
        error_input_IDX |= node_81.outputHasError_DONE;
        error_input_IDX |= node_78.outputHasError_DONE;
        error_input_IDX |= node_74.outputHasError_DONE;
        error_input_IDX |= node_71.outputHasError_DONE;
        error_input_IDX |= node_68.outputHasError_DONE;
        error_input_IDX |= node_64.outputHasError_DONE;
        error_input_IDX |= node_78.outputHasError_BYTE;
        error_input_IDX |= node_86.outputHasError_BYTE;
        error_input_IDX |= node_97.outputHasError_BYTE;
        error_input_IDX |= node_81.outputHasError_BYTE;
        error_input_IDX |= node_108.outputHasError_BYTE;
        error_input_IDX |= node_102.outputHasError_DONE;
        error_input_IDX |= node_155.outputHasError_OUT;
        error_input_IDX |= node_154.outputHasError_OUT;
        bool error_input_X0 = false;
        error_input_X0 |= node_102.outputHasError_BYTE;
        error_input_X0 |= node_97.outputHasError_DONE;
        error_input_X0 |= node_92.outputHasError_DONE;
        error_input_X0 |= node_86.outputHasError_DONE;
        error_input_X0 |= node_81.outputHasError_DONE;
        error_input_X0 |= node_78.outputHasError_DONE;
        error_input_X0 |= node_74.outputHasError_DONE;
        error_input_X0 |= node_71.outputHasError_DONE;
        error_input_X0 |= node_68.outputHasError_DONE;
        error_input_X0 |= node_64.outputHasError_DONE;
        error_input_X0 |= node_78.outputHasError_BYTE;
        error_input_X0 |= node_86.outputHasError_BYTE;
        error_input_X0 |= node_97.outputHasError_BYTE;
        error_input_X0 |= node_81.outputHasError_BYTE;
        error_input_X0 |= node_108.outputHasError_BYTE;
        error_input_X0 |= node_102.outputHasError_DONE;
        error_input_X0 |= node_155.outputHasError_OUT;
        error_input_X0 |= node_154.outputHasError_OUT;
        bool error_input_X1 = false;
        error_input_X1 |= node_102.outputHasError_BYTE;
        error_input_X1 |= node_97.outputHasError_DONE;
        error_input_X1 |= node_92.outputHasError_DONE;
        error_input_X1 |= node_86.outputHasError_DONE;
        error_input_X1 |= node_81.outputHasError_DONE;
        error_input_X1 |= node_78.outputHasError_DONE;
        error_input_X1 |= node_74.outputHasError_DONE;
        error_input_X1 |= node_71.outputHasError_DONE;
        error_input_X1 |= node_68.outputHasError_DONE;
        error_input_X1 |= node_64.outputHasError_DONE;
        error_input_X1 |= node_78.outputHasError_BYTE;
        error_input_X1 |= node_86.outputHasError_BYTE;
        error_input_X1 |= node_97.outputHasError_BYTE;
        error_input_X1 |= node_81.outputHasError_BYTE;
        error_input_X1 |= node_108.outputHasError_BYTE;
        error_input_X1 |= node_102.outputHasError_DONE;

        bool hasUpstreamError = false;
        hasUpstreamError |= error_input_IDX;
        hasUpstreamError |= error_input_X0;
        hasUpstreamError |= error_input_X1;

These computations consume flash. :frowning_face: :gun: The example above is a rollout of a single stage of the dataselect variadic node. And your example has maaany stages.

Well, I overlooked such scenarios and as a result, XOD 0.30 performs worse. I need some more time to find a solution to get back in terms of memory usage. If someone feels the power to solve this C++ riddle, help is much appreciated.

2 Likes

:sweat_smile:

I clarify that the initial test version was the v0.0.14 of my library.

In version 0.0.15 I did the compilation but when putting a loop in rtc there was a reading error that blocked my pc.

2 Likes

I did a test deactivating ERR on all the nodes of rtc and yes, the consumption of resources was reduced.

Sketch uses 20616 bytes (63%) of program storage space. Maximum is 32256 bytes.
Global variables use 1753 bytes (85%) of dynamic memory, leaving 295 bytes for local variables. Maximum is 2048 bytes.
Low memory available, stability problems may occur.
1 Like

At least we got an idea on how to improve the situation https://github.com/xodio/xod/issues/1832

It’s hard to predict how much memory it brings us back but I’m quite optimistic about it :crossed_fingers:

2 Likes