You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This was meant as a performance enhancement: when parsing a field, we only create a bignum if this field is going to be used for arithmetic operations, based on the analysis of the json. This has been causing many issues over time (in particular with header stacks, for each we end up enabling arithmetic on every field for every header in the stack pretty much as soon as the stack is referenced in an expression). The performance gain is also dubious.
It seems that a better & simpler solution (if we want to avoid enabling arith on every field by default) would be to do lazy on-demand conversion from the byte representation to the bignum integer representation and vice-versa.
For example, we could have a mutable boost::optional<bignum> int_ and a mutable boost::optional<ByteContainer> bytes_ members for the Data class (and get rid of the Field class ?).
When extracting a field, int_ would be set to none and bytes_ to the extracted value.
void add(const Data &src1, const Data &src2) {
if (src1.int_ == boost::none) src1.export_bytes();
if (src2.int_ == boost::none) src2.export_bytes();
this->int_ = src1.int_ + src2.int_;
}
etc
Note that we always have the following invariant: assert(this->int_ != boost::none || this->bytes_ != boost::none).
We would have to benchmark it on a complex P4 program (current approach vs proposed approach) but code modifications may not be too daunting. This new approach would be much less error-prone that the current one and I believe it has the potential of being faster despite the increased branching, given how conservative we have become with the enable arith method. Note how when copying one field to another we would not necessarily need to copy bignums or systematically export bytes like we do today.
The text was updated successfully, but these errors were encountered:
This was meant as a performance enhancement: when parsing a field, we only create a bignum if this field is going to be used for arithmetic operations, based on the analysis of the json. This has been causing many issues over time (in particular with header stacks, for each we end up enabling arithmetic on every field for every header in the stack pretty much as soon as the stack is referenced in an expression). The performance gain is also dubious.
It seems that a better & simpler solution (if we want to avoid enabling arith on every field by default) would be to do lazy on-demand conversion from the byte representation to the bignum integer representation and vice-versa.
For example, we could have a
mutable boost::optional<bignum> int_
and amutable boost::optional<ByteContainer> bytes_
members for theData
class (and get rid of theField
class ?).int_
would be set tonone
andbytes_
to the extracted value.Note that we always have the following invariant:
assert(this->int_ != boost::none || this->bytes_ != boost::none)
.We would have to benchmark it on a complex P4 program (current approach vs proposed approach) but code modifications may not be too daunting. This new approach would be much less error-prone that the current one and I believe it has the potential of being faster despite the increased branching, given how conservative we have become with the enable arith method. Note how when copying one field to another we would not necessarily need to copy bignums or systematically export bytes like we do today.
The text was updated successfully, but these errors were encountered: