Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the C++ standard allow for an implementation to coalesce allocations?

Tags:

c++

c++11

c++14

I was watching Jonathan Blow's video Ideas about a new programming language for games in which he discusses a common pattern in games programming he calls 'joint allocation'. The idea is when you have a class with several members that are dynamically allocated arrays (could be std::vector but since they're fixed size, more like the proposed std::dynarray) you pre-allocate enough memory to store all of the array data and perform only one allocation big enough for all the arrays rather than one for each array.

He proposes direct language support for this pattern which got me to wondering whether the C++ standard allows for implementations to coalesce allocations in this way? It strikes me that this would require some heroic effort from a compiler to actually implement as an optimization but I don't see an obvious reason why it couldn't be done in principle. Does anyone know if this would not be permitted under the standard, or even if there are already implementations that do this optimization in practice?

like image 306
mattnewport Avatar asked Nov 12 '14 19:11

mattnewport


1 Answers

Yes, the standard allows coalescing allocations (C++14):

5.3.4 New [expr.new]

10 An implementation is allowed to omit a call to a replaceable global allocation function (18.6.1.1, 18.6.1.2). When it does so, the storage is instead provided by the implementation or provided by extending the allocation of another new-expression. The implementation may extend the allocation of a new-expression e1 to provide storage for a new-expression e2 if the following would be true were the allocation not extended:

  • the evaluation of e1 is sequenced before the evaluation of e2, and
  • e2 is evaluated whenever e1 obtains storage, and
  • both e1 and e2 invoke the same replaceable global allocation function, and
  • if the allocation function invoked by e1 and e2 is throwing, any exceptions thrown in the evaluation of either e1 or e2 would be first caught in the same handler, and
  • the pointer values produced by e1 and e2 are operands to evaluated delete-expressions, and
  • the evaluation of e2 is sequenced before the evaluation of the delete-expression whose operand is the pointer value produced by e1.

C++11 did not allow coalescing or omitting such allocations.

like image 64
Deduplicator Avatar answered Oct 03 '22 11:10

Deduplicator