0

Starting with visual studio 2012 the SSE2 compile options are enabled per "default".
also for me it's about time to go ahead and utilize that feature - and no longer manually disable that flag for my projects.

However, I have seen many occasions where such program simply crashes when getting executed on an older processor that doesn't support SSE2.
for example see: Visual C++ 2012 cout crashes during run time

So I'd like to make this CPU feature a prerequisite and author some windows installer InstallCondition in WIX.
the installation should cancel and prevent the user from going through all the install procedure to only later find out that the program crashes and is incompatible with his system.

Is there any guidance how to implement such InstallCondition?

Community
  • 1
  • 1
Opmet
  • 1,754
  • 18
  • 20
  • I can recommend you a better solution: Intel Compiler supports generating two code paths. That way you can get benefit both performance and compatibility (in expanse of code size [and compiler license price]). – Rotem Oct 28 '16 at 20:57
  • 64-bit binaries don't need to check for SSE2 support; it's baseline for the architecture. You're right that there are still computers old enough for someone to conceivably still be using them, but not supporting SSE2 (AMD Athlon XP is the most recent non-SSE2 CPU. On Intel, it's Pentium III). – Peter Cordes Oct 29 '16 at 06:50
  • Doing this check at install time can be sub-optimal. If someone installs on an ancient computer, then uses the same install on a newer CPU, you're missing out. SSE2 is usually the baseline below which you give up and fall back to scalar C instead of hand-vectorized, so you're losing out on a lot this way. OTOH, it sucks to add overhead for checking at run time. Fortunately your x86-64 binaries don't have this problem. – Peter Cordes Oct 31 '16 at 00:37

2 Answers2

3

In year 2016, you'll hardly find a computer not supporting SSE2. So I would agree with others and suggest you just forget about that. But if you insist on doing this (most probably) premature optimization, you can create a custom action that checks that. The code is explained here:

UINT __stdcall CheckSSE2(MSIHANDLE hInstall)
{
    if (IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE))  // SSE2
        MsiSetProperty(hInstall, L"SSE2", L"1");

    return 0;
}

Then you can schedule this custom action to run before launch conditions and include "SSE2" property check in the launch conditions.

Community
  • 1
  • 1
Nikolay
  • 10,752
  • 2
  • 23
  • 51
1

i don't want to "steal" the answer by Nikolay, but i'd like to "extend" it.

so as nikolay referred to some other answer the solution is to call IsProcessorFeaturePresent:

UINT __stdcall checkCpuFeatureSSE2(MSIHANDLE hInstall)
{
    if (IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE))  // SSE2
        MsiSetProperty(hInstall, L"CPU_FEATURE_SSE2", L"1");

    return 0;
}

unfortunately this methods only allows to check for SSE2.
later versions of SIMD features are not covered: SSE42, AVX, AVX2, AVX512.

--

to check for those additional features i'm now using the reference implementation (as found in this answer) from: https://github.com/Mysticial/FeatureDetector
it calls __cpuid / __cpuidex from <intrin.h>.

for additional details see: https://msdn.microsoft.com/en-us/library/hskdteyh.aspx

so with this FeatureDetector (by Mysticial) i can now implement the desired LaunchCondition by adding:

DLLEXPORT VOID checkCpuFeatureSSE42(MSIHANDLE hMSI)
{
    FeatureDetector::cpu_x86 features;
    features.detect_host();
    if (features.HW_SSE42)
        MsiSetProperty(hMSI, "CPU_FEATURE_SSE42", "1");
}

DLLEXPORT VOID checkCpuFeatureAVX(MSIHANDLE hMSI)
{
    FeatureDetector::cpu_x86 features;
    features.detect_host();
    if (features.HW_AVX)
        MsiSetProperty(hMSI, "CPU_FEATURE_AVX", "1");
}

DLLEXPORT VOID checkCpuFeatureAVX2(MSIHANDLE hMSI)
{
    FeatureDetector::cpu_x86 features;
    features.detect_host();
    if (features.HW_AVX2)
        MsiSetProperty(hMSI, "CPU_FEATURE_AVX2", "1");
}

DLLEXPORT VOID checkCpuFeatureAVX512(MSIHANDLE hMSI)
{
    FeatureDetector::cpu_x86 features;
    features.detect_host();
    if (features.HW_AVX512_F)
        MsiSetProperty(hMSI, "CPU_FEATURE_AVX512", "1");
}

--

also see: https://stackoverflow.com/a/7495023

Opmet
  • 1,754
  • 18
  • 20