AVX2 support in Visual Studio

Started by
8 comments, last by Kaptein 5 years, 11 months ago

Is it possible to conditionally compile with /arch:AVX2 only if the CPU of the build system supports this set of instructions in Visual Studio?

After a quick Wikipedia check, I noticed that most of Intel's CPUs after 2011 (no Pentium and no Celeron) and of AMD's CPUs after 2013 seem to support AVX2. So I suppose for high rendering purposes it is still quite conservative to use /arch:AVX2 instead of /arch:SSE2? Or am I really cutting off a big part of the cake (I only care about x86/x64, not ARM/ARM64)?

🧙

Advertisement

Several game developers have been surprised by the prevalence of vocal Phenom II owners out there, which even lack SSE4.2 SSE 4.1.

I guess it's up to you to figure out how much of your market share you want to miss out on, and how many support cases you get opened by people who can't/won't read minspecs.

To make it is hell. To fail is divine.

I just noticed that although /arch:AVX2 is set for x86/x64, msvc++ 15.6.7 does not set __AVX2__?

🧙

I've got 15.6.7 and it set __AVX2__ for me, but ONLY at compile time.  Intellisense appears confused and is greying out my #ifdef __AVX2__ block.  The code inside the #ifdef actually ran though.

I've always done it manually .. detected CPU support at runtime with something like cpuid, and had multiple code paths for bottleneck code for different processors (it's kind of fun writing SIMD code!), I would be interested to know how good the compilers are at converting code to use SIMD themselves now.

Not really answering your question but ... If you were relying on the compiler to do the SIMD conversion, and you wanted to be lazy, you could also compile 2 / 3 different DLLs with different compile options and select at runtime? This is one of the suggestions here, which discusses some of the problems:

https://randomascii.wordpress.com/2016/12/05/vc-archavx-option-unsafe-at-any-speed/

Another possibility might be to look at the assembly generated for bottleneck areas, and either just copy this entirely, or use it as the basis for your own, or help identify areas where you could make it easier for the compiler to make it SIMD, as it is highly dependent on the data layout (caveat, I've not delved into examining compiler generated SIMD, I don't know how practical this is).

I do multiple builds and have a launcher pick the right one... :(

FWIW, the ispc language can do this though (and automatically pick the right version at runtime). 

While I understand wanting to get the latest and greatest CPU support, I'd be wary of it for most projects.

Targeting x64 enables many optimizations and benefits not accessible in 32-bit versions, and the Steam survey shows about 2% still using 32-bit Windows. 

For AVX2, while it is certainly nice for the compiler to take advantage of bigger registers and parallel optimizations, in practice the gain is minimal since that's not the typical bottleneck. The Steam survey says AVX (original, not 2) has about 89% adoption rate, and they don't list AVX2. 

Unless you have a specific algorithm you know is a bottleneck and you know needs to be implemented using AVX2 calls, I wouldn't bother with it. You probably have many more features you could pack into the game in the time it would take to hand-roll some code that takes advantage of the specific processor feature.

 

As a sidenote, i would not recommend to rely on the automatic vectorization of compilers. I did a bunch of test with various ones, gcc, g++, MSVC2015, MSVC2017(default and clang toolchain) and yes it does work, buuut breaks quite easily. So if you want to have that for speed, you should use intrinsics. Also, at least MSVC generated several codepaths with cpuid checks but only on the auto vectorized code.

You can detect support from CPUID and implement the AVX2 variant by detection if you really want to. If your compiler has multi-versioning support this is really easy (gcc, clang), otherwise I'm sure there are workarounds.

This topic is closed to new replies.

Advertisement