Простая библиотека заголовков в C / C++ для обнаружения функций процессора (поддерживаемый набор инструкций)
Я хотел бы создать простую функцию для определения характеристик процессора.
Мне это нужно для диспетчеризации времени выполнения путей кода функциями ЦП.
Я хотел бы что-то действительно простое, как:
hasSSE3()
, hasSSE4()
, hasAVX()
, hasAVX2()
, так далее..
Он должен быть переносимым, а именно поддерживать Windows, macOS и Linux.
Работать как на AMD, так и на процессорах Intel.
Например, как можно реализовать hasAVX()
?
замечание
Все, что меня волнует, это x86 (и только 64-битные процессоры).
Благодарю вас.
2 ответа
К сожалению, это не очень простая задача, если вы хотите, чтобы она была переносимой. Компиляторы обычно могут вам чем-то помочь, но функции у всех разные.
MSVC имеет __cpuid
встроенный в x86/x86_64, но, конечно, он не поддерживается в ARM. TBH Я не уверен, как получить возможности ЦП в MSVC, ориентируясь на ARM (или любую не-x86 арку).
Компиляторы, кроме MSVC, обычно маскируются под GCC, поэтому большинство из них будет поддерживать __builtin_cpu_init
/ __bulitin_cpu_supports
. встроенные функции
Для других компиляторов вам может понадобиться встроенная сборка, чтобы сгенерировать инструкцию CPUID и обработать результаты самостоятельно. Это поможет вам через x86/x86_64.
Вещи для других архитектур немного сложнее. Для ARM инструкция для получения информации о процессоре обычно недоступна для непривилегированного кода. Для glibc вы можете использовать getauxval
с AT_HWCAP
и / или AT_HWCAP2
, Для не-glibc Linux вам может понадобиться разобрать /proc/self/auxv и / или /proc/cpuinfo.
Одним из довольно надежных решений является новая библиотека Google cpu_features.
Если вы можете пожертвовать некоторой переносимостью, в Portable-Snippets есть модуль процессора (который я написал), который может помочь. Это не так надежно, как cpu_features, но гораздо проще интегрировать в ваш проект. Он должен работать почти везде на процессорах x86/x86_64, но поддержка ARM ограничена glibc, а другие архитектуры пока не поддерживаются.
Кажется, что библиотека Agner Fog- Vector Class Library (VCL) может сделать именно это.
Нужно просто включить vectorclass.h
в своем проекте и звоните instrset_detect()
,