英特尔工程师写道,我们应该使用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的以下情况:
广告材料声称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状态是否代价高昂,这将是一件好事?例如:
上面提到的关于检测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。
请告知。
答案 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; }
};