[Ovmsdev] RAM

Stephen Casner casner at acm.org
Thu Nov 2 11:32:04 HKT 2017


On Mon, 30 Oct 2017, Mark Webb-Johnson wrote:

> Looking at the m_metrics map storage, I tried a simple:
>
> std::forward_list<uint32_t> x;
>
[snip]
>
> That works out at 32 bytes per std::forward_list entry. That is
> presumably the 24 bytes for the allocation, plus 8 bytes per entry
> (a pointer to the next, plus a pointer to the entry content).

The 8 bytes are for a pointer to the next entry and then the 4 bytes
of the uint32_t itself.  The overhead of forward_list is only one
pointer.

> The absolute most efficient dynamic system would be an OvmsMetric*
> m_next in OvmsMetric, then a OvmsMetric* m_first in OvmsMetrics, and
> remove the map altogether. That would be 4 bytes for the OvmsMetrics
> list, plus an extra 4 bytes for each metric.
>
> The original design made a lot of use of MyMetrics.Find(), but that
> has been deprecated now and I don’t see anything using it at
> all. The only thing we need is a ‘metrics list’ iterator to show the
> details - all that needs is an ordered list.
>
> So, I went ahead and did that. Changed ovms_metrics to use a
> manually managed one-way linked list.

Removing the map is fine.  The overhead of forward_list is no more
than your own explicitly written m_next pointer, so if there is any
desire to keep the template for its available functions, you can.

> We could use a static style allocation (std::vector, or a static
> array), and fixed structures (rather than dynamic objects). That
> would save the allocation overhead, but would make things a lot more
> rigid.

There is an approach in between where you create a pool of blocks of a
given size by allocating some number of them in one malloc to amortize
the overhead, then dynamically hand out blocks from those pools.  When
you need more, you allocate another chunk of blocks.

                                                        -- Steve


More information about the OvmsDev mailing list