проверяет ли gcc __builtin_cpu_supports поддержку ОС?

Компилятор GCC предоставляет набор встроенных модулей для проверки некоторых функций процессора, таких как доступность определенных наборов инструкций. Но, согласно этой ветке мы также можем знать, что некоторые функции процессора могут быть не включены ОС. Итак, вопрос: __builtin_cpu_supports встроенные функции также проверяют, включила ли ОС определенную функцию процессора?


person Andrei R.    schedule 08.02.2018    source источник
comment
Это хороший вопрос. Некоторые люди отключают AVX из-за дросселирования для тестирования производительности. Я думаю, что с некоторыми процессорами Xeon Silver AVX512 может даже привести к снижению производительности в среднем из-за сильного троттлинга. Я не смотрел на это в то время. Думаю, с некоторыми версиями биоса AVX и выше можно отключить. В противном случае он может быть отключен ОС (хотя я не уверен, как это сделать). Я не знаю, что сообщает CPUID, если AVX отключен на уровне BIOS, но, вероятно, CPUID по-прежнему сообщает AVX.   -  person Z boson    schedule 13.02.2018
comment
В Windows вот как отключить AVX superuser.com/a/623738/230553. Я не уверен, как это сделать с Linux. Но если вы найдете, как вы можете легко проверить __builtin_cpu_supports и ответить на свой вопрос.   -  person Z boson    schedule 13.02.2018
comment
К сожалению, этот вопрос был закрыт stackoverflow.com/q/13965178/2542702   -  person Z boson    schedule 13.02.2018
comment
Я думаю, вам нужно добавить noxsave в параметры ядра для Linux.   -  person Z boson    schedule 13.02.2018
comment
@Zboson, вопрос действительно не в том, как включить/отключить avx, а в том, как проверить, включен ли он ОС   -  person Andrei R.    schedule 13.02.2018
comment
Я знаю. Но отключив AVX, я могу проверить, проверяет ли __builtin_cpu_supports ОС.   -  person Z boson    schedule 13.02.2018


Ответы (1)


No.

Я отключил AVX в своей системе Skylake, добавив noxsave в параметры загрузки ядра Linux. Когда я делаю cat /proc/cpuinfo, AVX (и AVX2) больше не появляются, и когда я запускаю код с инструкциями AVX, происходит сбой. Это говорит мне о том, что AVX отключен ОС.

Однако, когда я компилирую и запускаю следующий код

#include <stdio.h>

int main(void) {
  __builtin_cpu_init();
  printf("%d\n", __builtin_cpu_supports ("sse"));
  printf("%d\n", __builtin_cpu_supports ("avx"));
}

он возвращает 8 и 512. Это означает, что __builtin_cpu_supports не проверяет, был ли AVX отключен операционной системой.

person Z boson    schedule 13.02.2018
comment
Это действительно показывает, что GCC не проверяет, определен ли OSXSAVE. После этого необходимо также протестировать ОС stackoverflow.com/a/38345423/2542702. - person Z boson; 13.02.2018
comment
Вероятно, это следует считать ошибкой gcc; Обычно вы действительно хотите знать, действительно ли AVX можно использовать, а не поддерживает ли его только процессор. Если вы действительно хотите различать поддерживаемые ЦП, но не используемые, это при использовании CPUID вручную должно быть необходимо. Я предполагаю, что большая часть существующего кода, использующего __builtin_cpu_supports ("avx"), предполагает, что код, скомпилированный с помощью -mavx, может работать, если это правда. - person Peter Cordes; 13.02.2018
comment
@PeterCordes, это следует считать ошибкой. Я определенно ожидал, что он проверит, включен ли AVX ОС в моем ответе здесь. Кстати, что такое xsave и xgetbv. Почему есть два способа отключить AVX? Я предполагаю, что отключение xsave является более ограничительным. Как отключить AVX, не отключая xsave. - person Z boson; 14.02.2018
comment
Вы спрашиваете, как ОС в целом может отключить поддержку AVX, продолжая использовать одну из инструкций xsave* для сохранения регистров SSE/FPU/MPX при переключении контекста? Я думаю, что ОС все еще может просто использовать инструкцию без установки бита регистра управления, который указывает, что ОС обещает это сделать, поэтому инструкции AVX все равно будут ошибаться. IDK, если в Linux есть такая возможность. Или, может быть, все же установите этот бит, но не включите сохранение верхних половин ymm с помощью xsetbv. xgetbv — это инструкция по чтению расширенных управляющих регистров.. - person Peter Cordes; 14.02.2018
comment
@PeterCordes, я имею в виду, почему if ((xgetbv(0) & 6) != 6) проверяет, включен ли AVX в ОС. - person Z boson; 16.02.2018
comment
Это выражение проверяет 2 бита в расширенном управляющем регистре 0, чтобы увидеть, установлены ли они оба. Я думаю, что это биты, которые ОС должна установить с помощью xsetbv, чтобы обещать, что она будет использовать xsave для сохранения верхних половин ymm при переключении контекста, поэтому для ЦП безопасно разрешать выполнение инструкций AVX. Вы можете посмотреть точное значение этих битов, если хотите. - person Peter Cordes; 16.02.2018
comment
@PeterCordes, как ОС может блокировать инструкции? Я имею в виду, что я мог видеть, как все будет падать при переключении контекста, но возможно ли, что вы можете использовать AVX, например, только для чтения, которое не приведет к сбою. - person Z boson; 16.02.2018
comment
Ошибка инструкций AVX, если эти биты не установлены. AVX просто разработан таким образом, поэтому программы пользовательского пространства, поддерживающие AVX, в ядрах, не поддерживающих AVX, в худшем случае выдают ошибку #UD (SIGILL) вместо скрытого повреждения данных. SSE имеет аналогичный управляющий бит: ОС должна установить бит в управляющем регистре, иначе инструкции SSE ошибаются. Вы можете увидеть этот бит как обещание сохранить/восстановить регистры xmm. Но Intel, к сожалению, не предусмотрела простой способ для пользовательского пространства определить, если ОС установила этот бит. Это было ново для AVX. stackoverflow.com/a/34071400/224132 - person Peter Cordes; 16.02.2018
comment
В любом случае, смысл всего этого в том, что тихое повреждение данных при переключении контекста не является вероятным режимом отказа. Как правило, это может произойти только с ядром, поддерживающим AVX, но с ошибками. - person Peter Cordes; 16.02.2018