[Development] How qAsConst and qExchange lead to qNN
Marc Mutz
marc.mutz at qt.io
Mon Nov 14 18:30:54 CET 2022
Hi Ulf,
On 14.11.22 17:37, Ulf Hermann via Development wrote:
> Hi Marc,
>
>> On 11.11.22 09:35, Ulf Hermann via Development wrote:
>>> There is an undeniable benefit of _offering_ QSpan, QStringView, and
>>> generator APIs in a few relevant cases:
>>>
>>> 1. Users want to pass a "foreign" container to a Qt function that
>>> doesn't only store it as QList or QString. It might merely iterate it or
>>> store it as something else.
>>
>> The assumption that there's a problem only for "foreign containers" is
>> incorrect: Take the native Qt container QString as an example. See
>> assembly in my QAnyStringView blog post:
>> https://www.qt.io/blog/qstringview-diaries-qanystringview You have this
>> problem as soon as you pass constant data, which is a common enough
>> use-case to warrant optimizing for.
>
> My point is the "doesn't only store it as QList or QString" and
> "foreign" is in quotes quite on purpose. Maybe that wasn't clear enough,
> though.
>
> So, if the method immediately converts whatever it gets to QList or
> QString, then there is no point in passing it a span or view.
My point is that there _is_. Citing my blog post:
callConsumeQStringHelloWorld():
pushq %rbp
movl $12, %esi
leaq .LC76(%rip), %rdx
subq $32, %rsp
movq %rsp, %rbp
movq %rbp, %rdi
call QString::fromUtf8(QByteArrayView)@PLT
movq %rbp, %rdi
call consumeQString(QString const&)@PLT
movq (%rsp), %rax
testq %rax, %rax
je .L834
lock subl $1, (%rax)
je .L839
.L834:
addq $32, %rsp
popq %rbp
ret
.L839:
movq (%rsp), %rdi
movl $8, %edx
movl $2, %esi
call QArrayData::deallocate(QArrayData*, long long, long
long)@PLT
addq $32, %rsp
popq %rbp
ret
callConsumeQStringViewHelloWorld():
leaq .L.str.3401(%rip), %rsi
movl $12, %edi
jmp consumeQStringView(QStringView)@PLT # TAILCALL
It matters whether the QString/QList creation is in front of or behind
the ABI boundary. The size of the tst_qsettings executable for Clang
builds went down by >10% when the API was switched over to
QAnyStringView, without any changes to the test code itself (and
QAnyStringView hasn't even got the size/tag swap that Thiago pointed out
and that would make it require less gargantuan immediate values):
https://codereview.qt-project.org/c/qt/qtbase/+/353688
Sure, the sequence of assembler instructions is the same, but improved
code locality means it'll also execute a bit faster. Also, if we can
condense user code by 10% without changes to their code, then some users
may have an easier time right-sizing their embedded hardware, e.g.
Finally, to give you the very big picture: we have a duty to avoid
inflicting such egregiously inefficient code on the world. This bloat
needs to be stored: on disk, in RAM, in cache. At each of these levels,
the extra storage causes some pJ extra energy use, billions of times
over, causing corresponding CO2 emissions.
The German government has started dealing out the well-known "blue
angel" certificates for software now. Customers will eventually demand
our help in getting the energy use of their software down so they can be
certified.
We can, of course, ostrich on. But Qt is in a unique position, as a C++
native UI framework, to assist users in meeting climate goals. Think
about it: Would projects that prefer programmer productivity over
resource use inflict C++ on their programmers? Won't such projects
rather (continue to) use Java and HTML, shipping applications with a
bundled chromium to run a few HTML/JS apps in GiBs of memory instead of
MiBs (hello, MS Teams!)? To me, it sounds more logical that projects
that inflict C++ on their developers would be those projects that need
to meet resource usage goals (because of right-sizing of embedded
hardware or because they want to get certified as energy-efficient). And
all this talk about convenience trumping efficiency is going to raise
eyebrows in such projects.
Let's make C++ easy to use, for sure. But, sorry, using spans isn't
difficult. Don't confuse familiarity with simplicity.
Thanks,
Marc
--
Marc Mutz <marc.mutz at qt.io>
Principal Software Engineer
The Qt Company
Erich-Thilo-Str. 10 12489
Berlin, Germany
www.qt.io
Geschäftsführer: Mika Pälsi, Juha Varelius, Jouni Lintunen
Sitz der Gesellschaft: Berlin,
Registergericht: Amtsgericht Charlottenburg,
HRB 144331 B
More information about the Development
mailing list