【问题标题】:MSI install condition to check for CPU's SSE2 feature?MSI 安装条件以检查 CPU 的 SSE2 功能?
【发布时间】:2016-10-28 19:31:08
【问题描述】:

从 Visual Studio 2012 开始,SSE2 编译选项按“默认”启用。
对我来说,也是时候继续使用该功能了——不再为我的项目手动禁用该标志。

但是,我见过很多这样的程序在不支持 SSE2 的旧处理器上执行时崩溃
例如见:Visual C++ 2012 cout crashes during run time

所以我想将此 CPU 功能作为先决条件,并在 WIX 中编写一些 Windows 安装程序 InstallCondition
安装应该取消并阻止用户完成所有安装过程,以便以后发现程序崩溃并且与他的系统不兼容。

有没有指导如何实现这样的InstallCondition?

【问题讨论】:

  • 我可以向您推荐一个更好的解决方案:英特尔编译器支持生成两个代码路径。这样,您可以获得性能和兼容性(在代码大小 [和编译器许可证价格] 方面)的好处。
  • 64 位二进制文​​件不需要检查 SSE2 支持;它是架构的基线。你是对的,仍然有足够老的计算机可以想象仍然在使用它们,但不支持 SSE2(AMD Athlon XP 是最新的非 SSE2 CPU。在 Intel 上,它是 Pentium III)。
  • 在安装时执行此检查可能不是最佳选择。如果有人在旧计算机上安装,然后在较新的 CPU 上使用相同的安装,那么您就错过了。 SSE2 通常是您放弃并退回到标量 C 而不是手动矢量化的基线,因此您以这种方式失去了很多。 OTOH,增加运行时检查的开销很糟糕。幸运的是,您的 x86-64 二进制文件没有这个问题。

标签: windows wix windows-installer simd sse2


【解决方案1】:

在 2016 年,您几乎找不到不支持 SSE2 的计算机。所以我同意其他人的观点,并建议你忘记这一点。但是,如果您坚持这样做(很可能)过早优化,您可以创建一个自定义操作来检查它。代码解释here

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

    return 0;
}

然后您可以安排此自定义操作在启动条件之前运行,并在启动条件中包含“SSE2”属性检查。

【讨论】:

    【解决方案2】:

    我不想“窃取”answer by Nikolay,但我想“扩展”它。

    所以正如 nikolay 提到的some other answer,解决方案是调用IsProcessorFeaturePresent

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

    不幸的是,这种方法只允许检查 SSE2。
    later versions 未涵盖 SIMD 功能:SSE42、AVX、AVX2、AVX512。

    --

    为了检查我现在使用的参考实现(如在this answer 中找到)的那些附加功能:https://github.com/Mysticial/FeatureDetector
    它从<intrin.h> 调用__cpuid / __cpuidex

    更多详情请见:https://msdn.microsoft.com/en-us/library/hskdteyh.aspx

    所以有了这个 FeatureDetector (by Mysticial) 我现在可以通过添加来实现所需的 LaunchCondition:

    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");
    }
    

    --

    另见:https://stackoverflow.com/a/7495023

    【讨论】:

      猜你喜欢
      • 2017-01-04
      • 1970-01-01
      • 1970-01-01
      • 2015-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多