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

时间:2017-06-09 20:12:14

标签: avx avx2 xeon-phi avx512 knights-landing

英特尔工程师写道,我们应该使用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的以下情况:

  1. 对于64位模式下的两种指令(32位模式下30个时钟),Xeon Phi Knight着陆36个时钟周期都不需要这些指令。
  2. 这些说明非常便宜,在Xeon和Core处理器(Skylake / Kaby Lake)上是必需的,并且在可预见的未来将需要Xeon,以避免昂贵的过渡到非VEX状态。
  3. 广告材料声称Xeon Phi(Knights Landing)与其他Xeon处理器完全兼容。

    为避免VZEROUPPER / VZEROALL,是否有可靠的方法来检测Xeon Phi?

    有一篇文章"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)或Core处理器,因此它们也将支持AVX-512F + CD + ER + PF功能骑士登陆介绍?

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

    请告知。

1 个答案:

答案 0 :(得分:1)

如果您特别想要检查是否使用KNL(而不是更通用的&#34;我运行的CPU是否具有功能X?&#34;)您可以通过查看&#来做到这一点34;大家庭&#34;,&#34;家庭&#34;和&#34;模型&#34;使用%eax == 1和%ecx == 0调用cpuid之后%eax中的字段。下面的C ++代码将完成这项工作。

然而,正如其他人暗中指出的那样,这是一个非常具体的测试,例如,将在未来的Knights核心上失败,所以你可能会更好地按照建议并检查AVX-512功能不在Xeon,所以AVX512-ER和AVX512-PF。 (当然,这样的指示可能会出现在未来的Xeons中,所以从长远来看这并不能保证,但引用凯恩斯:&#34;从长远来看,我们已经全部死了&#34;: - ))< / p>

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