[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