[Interest] Tricks to improve moc performance?

Adam Light aclight at gmail.com
Fri Dec 6 02:09:44 CET 2019


We have several machines running Windows 10 that are quite powerful (eg. 8
or 16 core (16 or 32 thread) processors, lots of RAM, NVMe SSD storage).
However, since upgrading to Windows 1903, we have noticed that sometimes
the compile time of our large Qt 5.12 based application increases
dramatically.

As an example, on one 16 core/32 thread machine, a debug build can take as
little as 4 minutes. However it sometimes takes 18 minutes. This is for the
exact same code, compiler, settings, etc. I can literally do a full build
that takes 4 minutes, do something, delete the build directory and rebuild
and now it takes 16 minutes. The "do something" may be going to lunch or
making a trivial change in the code. Otherwise the state of the machine is
the same (no other heavyweight processes running, etc.)

We see this behavior both when using Qt Creator 4.10.2 to do the build
(using jom.exe) and also when done outside of Creator with calls to qmake
and then jom. All files involved in anything I mention here are on and/or
written to the local SSD. I see these issues with no antivirus running, no
backup, etc.

I have collected some Windows Performance Tracing traces while building and
during a "slow" build, most of the time is spent in moc, specifically
searchIncludePaths. This function results in a lot of calls to
QFileInfo::exists() and QFileInfo::isDir(), both of which ultimately call
GetFileAttributesExW. The vast majority of the time is spent in downstream
calls that GetFileAttributesExW makes, so I am not blaming moc itself for
the slowdown.

I don't want to get too much into the weeds, but I believe that the
slowdown is a bug in one or more Windows minifilter drivers, which get
invoked by the OS in the file API calls. I suspect that pinpointing the
problem in such a way that I could report it to Microsoft is unlikely, and
so for practical reasons I am hoping that there is a way we could change
our build process to work around this slowdown.

Our application is one that was ported into Qt and we are building a few
very small libraries and one gigantic application that links to those
libraries. This isn't ideal, I'm sure, but I don't think it would be
practical to disentangle everything to have separate projects that are
first built and then linked into the main application.

We have almost 600 classes that use Q_OBJECT, so there are a lot of calls
to moc. We probably don't strictly need the Q_OBJECT macro in some of those
classes, but I would prefer not to start removing Q_OBJECT unless that's
the last option.

We also have around 200 paths in our INCLUDEPATH variable. Moving header
files into fewer directories would allow that to decrease, which should
improve moc performance.

Does anyone else have any ideas of how we could change our build to improve
moc performance when Windows decides to be "slow"? Like, for example, is
there any way to have the moc calls run with only a few moc processes
running at once but have the rest of the build done with all threads
running. I'm pretty sure that the OS slowdown has something to do with
thread contention of some sort.

If anyone thinks they have run into this situation or is intimately
familiar with Windows minifilter drivers, I'm happy to share the details
behind why I think they are involved here.

Thanks for any ideas
Adam
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20191205/214095ad/attachment.html>


More information about the Interest mailing list