首页 文章

如何检测Xeon Phi(骑士登陆)

提问于
浏览
0

英特尔工程师写道,我们应该使用VZEROUPPER / VZEROALL来避免在所有处理器(包括未来的Xeon处理器)上转移到非VEX状态,但不能在Xeon Phi上转换:https://software.intel.com/pt-br/node/704023

人们还测量并发现VZEROUPPER和VZEROALL在Knights Landing上很贵:

在64位模式下,两个指令都有36个时钟周期(32位模式下为30个时钟) .

见上面的链接 .

所以我的代码将如下,如果我刚刚使用了ymm0和ymm1:

if [we are running on a Xeon Phi]
     vpxor       ymm0,ymm0,ymm0
     vpxor       ymm1,ymm1,ymm1
else
     vzeroall
endif

如何检测Xeon Phi(Knights Landing和后来的Xeon Phi处理器)来实现上述代码?

我们现在有关于VZEROUPPER / VZEROALL的以下情况:

  • 对于64位模式下的两个指令(32位模式下为30个时钟),Xeon Phi Knight着陆36个时钟周期不需要这些指令 .

  • 这些说明非常便宜,在Xeon和Core处理器(Skylake / Kaby Lake)上是必需的,并且在可预见的未来将需要Xeon,以避免代价高昂地过渡到非VEX状态 .

广告材料声称Xeon Phi(Knights Landing)与其他Xeon处理器完全兼容 .

有没有可靠的方法来检测Xeon Phi,以避免使用VZEROUPPER / VZEROALL?

有一篇文章"How to detect Knights Landing AVX-512 support (Intel® Xeon Phi™ processor)" by James R., Updated February 22, 2016,但它只关注Knights Landing上可用的特定新指令 . 因此,对于VEX过渡仍然不是很清楚 .

如果知道英特尔是否计划实施CPUID位以显示非VEX状态是否代价高昂,那将是一件好事?例如:

  • 位设置为0 - VEX状态转换成本很高,但VZEROUPPER / VZEROALL价格便宜,应该用于清除状态;

  • 位设置为1 - 没有转换惩罚,不需要VZEROUPPER / VZEROALL .

上面提到的关于检测Knights Landing的文章建议检查Knights Landing中引入的AVX-512F CD ER PF位 .

所以代码建议立即检查所有这些位,如果全部都已设置,那么我们就是Knights Landing:

uint32_t avx2_bmi12_mask = (1 << 16) | // AVX-512F
                           (1 << 26) | // AVX-512PF
                           (1 << 27) | // AVX-512ER
                           (1 << 28);  // AVX-512CD

如果英特尔计划在不久的将来将这些所有位添加到简单的Xeon(非Phi)或核心处理器中,那将是一件好事,因此它们也将支持Knight Landding中引入的AVX-512F CD ER PF功能?

如果Xeon和Core处理器支持AVX-512F CD ER PF,我们将无法将Xeon与Xeon Phi区分开来 .

请指教 .

1 回答

  • 1

    如果您特别想检查是否在KNL上(而不是更一般的“我运行的CPU是否具有功能X?”),您可以通过查看“扩展系列”,“系列”和“模型”来实现“在使用%eax == 1和%ecx == 0调用cpuid之后%eax中的字段 . 下面的C代码将完成这项工作 .

    但是,正如其他人暗中指出的那样,这是一个非常具体的测试,例如,将在未来的Knights核心上失败,因此您可能会更好地按照建议并检查不在的AVX-512功能Xeon,AVX512-ER和AVX512-PF . (当然,这样的指示可能出现在未来的Xeons中,所以从长远来看这并不能保证,但引用凯恩斯:“从长远来看,我们都死了”:-))

    class cpuidState
    {
        uint32_t orig_eax;                      /* Values sent in to the cpuid instruction */
        uint32_t orig_ecx;
    
        uint32_t eax;                           /* Values received back from it. */
        uint32_t ebx;
        uint32_t ecx;
        uint32_t edx;
    
        void cpuid()
        {
            __asm__ __volatile__("cpuid"
                                 : "+a" (eax), "=b" (ebx), "+c" (ecx), "=d" (edx));
        }
    
        void update (uint32_t eaxVal, uint32_t ecxVal)
        {
            orig_eax = eaxVal;
            orig_ecx = ecxVal;
            eax      = eaxVal;
            ecx      = ecxVal;
            cpuid();
        }
    
        void ensureCorrectLeaf(uint32_t eaxVal, uint32_t ecxVal)
        {
            if (orig_eax != eaxVal || orig_ecx != ecxVal)
                update (eaxVal, ecxVal);
        }
    
     public:
        cpuidState() : orig_eax (-1), orig_ecx(-1) { }
    
        // Include the Extended Model in the test. Without it we see some Xeons as KNL :-(
        bool onKNL()            { ensureCorrectLeaf(1,0); return (eax & 0x0f0ff0) == 0x50670; }    
    };
    

相关问题