[Development] Updating x86 SIMD support in Qt

Thiago Macieira thiago.macieira at intel.com
Wed Jan 19 17:55:46 CET 2022


On Wednesday, 19 January 2022 05:04:07 PST Tor Arne Vestbø wrote:
> Hey hey,
> 
> On 19 Jan 2022, at 04:01, Thiago Macieira
> <thiago.macieira at intel.com<mailto:thiago.macieira at intel.com>> wrote:
 
> 3) add a way to have multi-arch glibc-based Linux builds
> 
> If we go down this road I ask that we align both the porcelain and plumbing
> (configure, build system, C++ APIs, etc) . We already have universal builds
> on macOS and iOS done one way, and multi-arch/abi on Android another way.
> Let’s not add a third slightly different way, but instead use the
> opportunity to pay off some of the technical debts in this area.

I don't know how Android does this. I'll take some time to study and get back 
to you.

macOS is different because it's done by the compiler: you ask for an universal 
build and the compiler does it for you. We have to be careful of the extra 
files that are arch-specific, but that can be solved at the source level.

I'm not sure how much can be shared because they're trying to solve different 
problems.
 
> One data point here, that I don’t know is worth anything, is that on macOS
> 12 at least, none of the system binaries in /bin or /sbin are x86_64h, they
> are all x86_64+arm64e (arm64e reserved for Apple for now).

I don't think they ever were x86_64h. The trick is in the libraries in 
/usr/lib and in /System/Library/Frameworks. For example:

$ (cd /System/Library/Frameworks/CoreFoundation.framework/; file -L 
CoreFoundation)
CoreFoundation: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 
64-bit dynamically linked shared library x86_64] [x86_64h]
CoreFoundation (for architecture x86_64):       Mach-O 64-bit dynamically 
linked shared library x86_64
CoreFoundation (for architecture x86_64h):      Mach-O 64-bit dynamically 
linked shared library x86_64h

This is what I'm proposing: that we update *libraries* not applications.
 
> It might also need some more work than just changing our default. E.g,
> changing the arch in a simple Xcode project gives:
 
> The run destination My Mac is not valid for Running the scheme
> 'rasterwindow’.
 My Mac doesn’t support any of rasterwindow.app’s
> architectures. You can set rasterwindow.app’s Architectures build setting
> to Standard Architectures to support My Mac. 
> This is on a 2019 MBP

That means the Xcode solution is lacking, not the OS is.

$ cat hello.c 
#include <stdio.h>
int main() { puts("Hello, World!"); }
$ /Applications/Xcode.app/Contents/Developer/Toolchains/
XcodeDefault.xctoolchain/usr/bin/clang \
	-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/
MacOSX.platform/Developer/SDKs/MacOSX.sdk \
	-arch x86_64h -arch arm64e hello.c
$ file a.out 
a.out: Mach-O universal binary with 2 architectures: [x86_64h:Mach-O 64-bit 
executable x86_64h] [arm64e:Mach-O 64-bit executable arm64e]
a.out (for architecture x86_64h):       Mach-O 64-bit executable x86_64h
a.out (for architecture arm64e):        Mach-O 64-bit executable arm64e
$ ./a.out 
Hello, World!

I'm not proposing we change Xcode project file generation. Only Qt's own 
CMake-based build.

> I believe we detect that situation at runtime and explicitly turn off AVX
> support, so we wouldn’t be hitting any of those AVX code paths, if I
> understand things correctly?

No, that's not what I meant. You're referring to the current solution, which 
is that macOS binaries are x86-64-v2 and runtime select some extra features in 
QtGui. When run inside Rosetta2, the CPUID will tell the binaries that AVX is 
unavailable and they wouldn't be enabled.

What I'm proposing is that we skip the CPUID detection and enable AVX2 
everywhere, by using x86_64h for all of Qt's content. This would apply to 
QtCore and qt3d, which do have AVX2 content that isn't getting enabled and 
thus is leaving performance on the table. But if run inside Rosetta2, it will 
either crash or fail to load in the first place due to the missing x86_64 
architecture inside the fat binary.

Why am I even asking this if we have ARM builds? I was thinking of 
applications that are forced to remain on x86-64 because of some other content 
(theirs or, usually, a proprietary third-party) that does not offer an ARM 
version. This was the reason that Apple kept the 32-bit x86 for a long time 
after they stopped supporting that processor with updates and so did we. Those 
people would need to download Qt sources and rebuild using x86_64 as the 
target (they can probably disable the ARM builds too).

I'm thinking that those are the minority and exception to the rule. They're 
often commercial customers, though, but I guess Qt Company will happily take 
their money and make a special build for them. Meanwhile, everyone else is 
leaving performance on the table.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel DPG Cloud Engineering





More information about the Development mailing list