Как обнаружить Xeon Phi (приземление рыцарей)
Инженеры Intel написали, что мы должны использовать VZEROUPPER/VZEROALL, чтобы избежать дорогостоящего перехода в состояние без VEX на всех процессорах, включая будущий процессор Xeon, но не на Xeon Phi: https://software.intel.com/pt-br/node/704023
Люди также измерили и выяснили, что VZEROUPPER и VZEROALL дорогие на Knights Landing:
36 тактов для обеих команд в 64-битном режиме (30 тактов в 32-битном режиме).
Смотрите выше ссылку.
Поэтому мой код будет следующим, если я только что использовал 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:
- Эти инструкции не нужны и стоят очень дорого на 36 тактах Xeon Phi Knight Landing для обеих команд в 64-битном режиме (30 тактов в 32-битном режиме).
- Эти инструкции очень дешевы и необходимы для процессоров Xeon и Core (Skylake/Kaby Lake) и понадобятся Xeon в обозримом будущем, чтобы избежать дорогостоящего перехода в состояние без VEX.
В рекламных материалах утверждается, что Xeon Phi (Knights Landing) полностью совместима с другими процессорами Xeon.
Есть ли надежный способ обнаружить Xeon Phi, чтобы избежать VZEROUPPER/VZEROALL?
Статья Джеймса Р. " Об обнаружении поддержки Knights Landing AVX-512 (процессор Intel® Xeon Phi™)" обновлена 22 февраля 2016 г., но в ней рассматриваются только конкретные новые инструкции, которые стали доступны в Knights Landing. Так что до сих пор не очень ясно о переходах VEX.
Было бы хорошо узнать, планирует ли Intel реализовать бит CPUID, чтобы показать, дорого ли состояние без VEX? Например:
- Бит установлен в 0 - переходы состояния VEX являются дорогостоящими, но VZEROUPPER/VZEROALL дешевы и должны использоваться для очистки состояния;
- Бит установлен в 1 - штраф за переход отсутствует, VZEROUPPER/VZEROALL не требуется.
Вышеупомянутая статья об обнаружении посадки Рыцарей предлагает проверить биты AVX-512F+CD+ER+PF, как представлено в Посадке Рыцарей.
Таким образом, код предлагает проверить все эти биты сразу, и если все они установлены, то мы находимся на месте посадки рыцарей:
uint32_t avx2_bmi12_mask = (1 << 16) | // AVX-512F
(1 << 26) | // AVX-512PF
(1 << 27) | // AVX-512ER
(1 << 28); // AVX-512CD
Было бы хорошо узнать, планирует ли Intel добавить все эти биты в простые процессоры Xeon (не Phi) или Core в ближайшем будущем, поэтому они также будут поддерживать функции AVX-512F+CD+ER+PF, представленные в Рыцарь Лендинг?
В случае, если процессор Xeon и Core будут поддерживать AVX-512F+CD+ER+PF, мы не сможем отличить Xeon от Xeon Phi.
Пожалуйста, порекомендуйте.
1 ответ
Если вы специально хотите проверить наличие KNL (а не более общего "Имеет ли процессор, на котором я работаю, функцию X?"), Вы можете сделать это, взглянув на "Расширенное семейство", "Семейство" и "Модель". msgstr "поля в%eax после вызова cpuid с%eax==1 и%ecx == 0. код 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; }
};