对于检查CPU是否支持SSE3指令集,以下代码是否有效?
在Windows XP上使用IsProcessorFeaturePresent()
函数显然不起作用(参见http://msdn.microsoft.com/en-us/library/ms724482(v=vs.85).aspx。
bool CheckSSE3()
{
int CPUInfo[4] = {-1};
//-- Get number of valid info ids
__cpuid(CPUInfo, 0);
int nIds = CPUInfo[0];
//-- Get info for id "1"
if (nIds >= 1)
{
__cpuid(CPUInfo, 1);
bool bSSE3NewInstructions = (CPUInfo[2] & 0x1) || false;
return bSSE3NewInstructions;
}
return false;
}
发布于 2014-03-20 09:22:28
Mysticial的答案有点危险--它解释了如何检测CPU支持,而不是操作系统支持。您需要使用_xgetbv检查操作系统是否启用了所需的CPU扩展状态。有关其他来源的信息,请参阅here。Even gcc has made the same mistake.代码的要点是:
bool avxSupported = false;
int cpuInfo[4];
__cpuid(cpuInfo, 1);
bool osUsesXSAVE_XRSTORE = cpuInfo[2] & (1 << 27) || false;
bool cpuAVXSuport = cpuInfo[2] & (1 << 28) || false;
if (osUsesXSAVE_XRSTORE && cpuAVXSuport)
{
unsigned long long xcrFeatureMask = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
avxSupported = (xcrFeatureMask & 0x6) == 0x6;
}
发布于 2015-02-11 04:53:25
经过相当多的谷歌搜索,我也找到了来自英特尔的解决方案:
void cpuid(uint32_t eax, uint32_t ecx, uint32_t* abcd) {
#if defined(_MSC_VER)
__cpuidex((int*)abcd, eax, ecx);
#else
uint32_t ebx, edx;
# if defined( __i386__ ) && defined ( __PIC__ )
/* in case of PIC under 32-bit EBX cannot be clobbered */
__asm__("movl %%ebx, %%edi \n\t cpuid \n\t xchgl %%ebx, %%edi" : "=D" (ebx),
# else
__asm__("cpuid" : "+b" (ebx),
# endif
"+a" (eax), "+c" (ecx), "=d" (edx));
abcd[0] = eax; abcd[1] = ebx; abcd[2] = ecx; abcd[3] = edx;
#endif
}
int check_xcr0_ymm()
{
uint32_t xcr0;
#if defined(_MSC_VER)
xcr0 = (uint32_t)_xgetbv(0); /* min VS2010 SP1 compiler is required */
#else
__asm__("xgetbv" : "=a" (xcr0) : "c" (0) : "%edx");
#endif
return ((xcr0 & 6) == 6); /* checking if xmm and ymm state are enabled in XCR0 */
}
还要注意,GCC有一些可以使用的特殊内部函数(请参阅:https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/X86-Built-in-Functions.html ):
if (__builtin_cpu_supports("avx2"))
// ...
如果你把这些和上面的信息放在一起,一切都会好起来的。
https://stackoverflow.com/questions/6121792
复制相似问题