[Development] What's Q_PRIMITIVE_TYPE for?
thiago.macieira at intel.com
Fri Nov 13 07:48:21 CET 2020
On Thursday, 12 November 2020 07:07:53 PST Lars Knoll wrote:
> So except for the memset(0) for default construction, Primitive and Trivial
> have the same conditions in your list here. My proposal would be to drop
> the memset(0) optimisation and with that unify those two groups.
Not exactly. The distinctions come up at these points (see 2 and 3):
1) extending the container with new elements (resize() with sufficient
capacity already allocated or constructor with element count): memsettable
types can benefit from memset(0), as can most trivial types, except those
2) reallocating the container: relocatable types (which include all trivially-
copyable types) can be relocated by memcpy, which in turn means they can be
relocated by realloc().
2b) relocating elements without reallocating (insertion): same as #2
3) detaching: trivially copyable types can be copied with memcpy(), but
relocatable ones cannot
Q_PRIMITIVE_TYPE is currently something more restrictive than trivial type
because of #1.
> (Note: I'm completely ignoring the lifetime issues at just blessing a block
> of memory and saying "there are N objects here". Thiago is right, we
> shouldn't ignore that. But I'm not sure how, except by biting the bullet
> and calling constructors/destructors, then relying on the compiler to do
> the right thing.)
> Those lifetime issues need to be tackled differently. One option could be to
> abandon all our optimizations in a checked build, and only enable them in
> release mode.
We have to assume that any build with optimisations turned on means a checked
build. Therefore, your proposal is self-contradictory.
I propose we ignore the lifetime issues *for* *now*. We need a proper language
solution to declare objects' lifetime has started when we do either of the
three operations above, without loss of performance afforded by the memcpy /
memset. So either the language gives us a std::launder-like interface to bless
the fait accompli or the compilers give us equivalent performance without such
an interface. The relocation of non-trivially copyable types will likely have
a language update because the current direction seems to include adding a
destructive move operation.
But we will not be able to ignore the problem forever and I think the bill
will come due before the end of the Qt 6 lifetime. For that reason, I am
asking we decide which of the above is worth. I think:
1) not worth memsetting and very likely the compilers can be fixed to
optimise. The benefit of memset compared to the whole operation (including
malloc()) may not be worth the hassle
2) worth it because the language seems to be going in the direction we want
and have showed the way for the last 15 years (relocatable types, destructive
3) uncertain; if the compilers do #1, it's likely they'll do #3 too.
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel DPG Cloud Engineering
More information about the Development