#pragma XOD dirtiness disable


#1

In the code for the “concat” patch node for strings it has this pragma as so:

#pragma XOD dirtieness disable

struct State {
    ConcatListView<char> view;
};

{{ GENERATED_CODE }}

void evaluate(Context ctx) {
    auto state = getState(ctx);
    auto head = getValue<input_IN1>(ctx);
    auto tail = getValue<input_IN2>(ctx);
    state->view = ConcatListView<char>(head, tail);
    emitValue<output_OUT>(ctx, XString(&state->view));
}

Anyone know the purpose of this directive?


#2

This directive is an optimization hint for the transpiler. It tells that it is not necessary to store so-called dirtiness flags for node output pins.

Some nodes can emit a value on one output, but keep another intact. In these cases, the dirtiness flags allow determining whether emitValue for a particular output was called or not. However, when a node emits a new value on every evaluate regardless of conditions, we can disable the flags and just assume the outputs are always dirty after the evaluation. This way we save a byte of RAM and a few clock cycles per transaction.

As a rule of thumb: pure functional nodes (in math sense) should disable the dirtiness.


#3

Thanks, very handy to know. I managed to get my variadic parallel-to-serial converter working correctly (will upload revised version), all the nodes in that are essentially functional in the sense you describe. Adding the pragma to them provided a significant program memory usage reduction without affecting the functionality. But you say the savings are in RAM so don’t know if that’s expected…


#4

Yeah, it saves some RAM and Flash. SRAM is the most precious resource on microcontrollers so I’ve emphasized it. Nevertheless, some code is thrown away as well, so the Flash consumption is cut as well.