Page MenuHome

BLI: Add new `blender::Pool` container
ClosedPublic

Authored by Clément Foucault (fclem) on Sep 6 2022, 1:28 PM.

Details

Summary

A blender::Pool can construct and destruct elements without reordering. Freed items memory
will be reused by next allocations.

Elements are allocated in chunks to reduce memory fragmentation and avoid reallocation.

Diff Detail

Repository
rB Blender

Event Timeline

Clément Foucault (fclem) requested review of this revision.Sep 6 2022, 1:28 PM
Clément Foucault (fclem) created this revision.
  • Simplify implementation and rename to blender::Pool
Clément Foucault (fclem) retitled this revision from BLI: Add new `IndexedPool` container to BLI: Add new `blender::Pool` container.Sep 6 2022, 3:58 PM
Clément Foucault (fclem) edited the summary of this revision. (Show Details)
Jacques Lucke (JacquesLucke) requested changes to this revision.Sep 6 2022, 4:04 PM
Jacques Lucke (JacquesLucke) added inline comments.
source/blender/blenlib/BLI_pool.hh
7

Not sure what the reordering part means now, would probably just remove this.

Maybe add a description of a simple use case and comparison to different data structures we have already.

20

Don't think we have a rule for that yet, I'd use ChunkLen in my code for template parameters, but don't mind either way.

20

Derive from NonCopyable just to be more explicit.

26

The comment is only partially correct. This stack can also contain elements that have never been freed before.
Also mention why a Stack instead of some other container is used.

Since the inline buffer of the stack will overflow on the allocation of the first chunk already, we can also remove the inline buffer and make Pool smaller. (Stack<T *, 0>)

30

No need to define a constructor when it's trivial.

41

Return a reference instead of pointer (mainly to indicate that null is never returned).

43

Use is_empty instead.

46

Just doing individual pushes is probably faster here.

source/blender/blenlib/tests/BLI_pool_test.cc
17

Would be good to have a test that checks that previous allocations are actually reused.

This revision now requires changes to proceed.Sep 6 2022, 4:04 PM
  • Address review comments
Jacques Lucke (JacquesLucke) added inline comments.
source/blender/blenlib/BLI_pool.hh
30

typo (list)
Another reason is that stack offers better cache performance than e.g. a queue, because the memory is more likely to be in cache still.

45

Use is_empty.

This revision is now accepted and ready to land.Sep 6 2022, 5:04 PM

Maybe it's a dumb question, but what benefit does a vector of chunks have over a single vector of elements?

source/blender/blenlib/BLI_pool.hh
9

NonMovable is just a Blender thing, it might be clearer to just say "not moveable" here.

29

to be use for next -> to be used for the next

36

elements needs to -> elements need to

41

this pool memory -> this pool's memory

The choice for a vector of chunks is multiple:

  • Less memory fragmentation.
  • blender::Vector does not allow destroyed object inside it.
  • Elements need to keep the same addresses in order to be free using it. So no vector reallocation.

I was interested to see the new container, if possible, I will add my thought.
This container has specifics. Now you can understand that the wrong object is being processed for the reason that it will most likely be nullptr.
But with a pool, it is not a fact that it will be clear if a mistake was made and the wrong object is calculated.
This could be added as a warning, in case someone notices when using this container that the object is not being selected correctly.

Not my expertise, it might be a dumb question, but since Blender has a BLI_mempool, if this blender:Pool has similar usage (with advantages), would it be nice to replace the BLI_mempool code with this new one? (instead of having two similar implementations)?

@Germano Cavalcante (mano-wii) Yes this is kind of a lightweight version of the BLI_mempool. However, this is a C++ implementation only and does not cover all the use cases of the mempool. This is meant to be a simple replacement for now but could be declined into IterablePool later if needed.

@Iliya Katueshenock (Moder) I am not sure I get what you are trying to say. There is no real safety mechanism here because there is no fast way to make sure a given object is from this pool or is even still constructed. This would require more data and complexity to add this check and it would slow down the debug builds. I don't really need that right now but I do see its potential.

This revision was automatically updated to reflect the committed changes.