[Development] Reducing number of allocations in metacall argument marshalling
Olivier Goffart
olivier at woboq.com
Thu Jan 16 11:44:47 CET 2014
On Wednesday 15 January 2014 13:42:01 Kuba Ober wrote:
> Currently, the metacall arguments are marshaled by copy-constructing them in
> their own heap blocks. The addresses to the copies are deposited in an
> array-of-void*, passed as the args argument to QObject::qt_metacall etc.
>
> So there are two layers of allocations:
>
> 1. An array of void* is heap-allocated.
> 2. It’s filled with pointers to heap-allocated copies of each argument.
>
> The void** args protocol can be preserved, but instead of allocating copies
> on the heap, they could be in-place-constructed right after the pointers.
> So args would be an array that has:
>
> pointer-to-return-value-instance
> pointer-to-arg1-instance
> …
> pointer-to-argn-instance
> nullptr
> return-value-instance
> arg1-instance
> …
> argn-instance
>
> If any of the pointers is zero, the instance would not be present in the
> array (it will not occupy an instance space).
>
> The metatype system stores the size of types known to it, so it’s a simple
> matter to know how big the all-in-one array needs to be, taking alignment
> into consideration, of course.
>
> I don’t know yet if such a change would be binary compatible, that needs
> further checking of course. Initially it looks as if it would be
> compatible, since the QMetaCallEvent class is internal only, just as
> queued_activate is etc.
>
> I would like to know if such a change would be considered useful. The
> potential for underlying allocator global lock contention is much smaller,
> besides not paying the uncontested lock allocation costs, and simply using
> a bit less memory for every metacall event.
>
> As an extension of this approach, one could provide a factory method in
> `QMetaCallEvent` that would allocate the proper amount of memory all in one
> go (to fit the event, the arguments, and possibly the types when it owns
> the types).
>
> Does this make sense?
Yes, it's a good idea.
Note that you are only talking about queued connection here, because direct
connection put the array on the stack.
You could even add a QVarLenghtArray in QMetaCallEvent to hold the data.
Notice that I noticed that sometimes, two small allocations are faster than a
big allocation.
--
Olivier
Woboq - Qt services and support - http://woboq.com - http://code.woboq.org
More information about the Development
mailing list