Обнаружение времени компиляции архитектуры ЦП
-
02-07-2019 - |
Вопрос
Какой самый надежный способ узнать архитектуру ЦП при компиляции кода C или C++?Насколько я могу судить, разные компиляторы имеют свой набор нестандартных определений препроцессора (_M_X86
в МСВС, __i386__
, __arm__
в GCC и т. д.).
Есть ли стандартный способ определить архитектуру, для которой я создаю?Если нет, существует ли источник полного списка таких определений для различных компиляторов, например заголовок со всеми шаблонами #ifdef
с?
Решение
Вот некоторая информация о Предопределенные макросы архитектуры и другие типы предопределенных макросов.
Этот вопрос спрашивает, где они определены в исходном коде GCC.
Другие советы
Межкомпиляторного стандарта не существует, но каждый компилятор имеет тенденцию быть вполне последовательным.Вы можете создать для себя заголовок примерно так:
#if MSVC
#ifdef _M_X86
#define ARCH_X86
#endif
#endif
#if GCC
#ifdef __i386__
#define ARCH_X86
#endif
#endif
Полный список не имеет особого смысла, поскольку существуют тысячи компиляторов, но широко используются только 3-4 (Microsoft C++, GCC, Intel CC, может быть, TenDRA?).Просто решите, какие компиляторы будет поддерживать ваше приложение, перечислите их #define и при необходимости обновите заголовок.
Если вы хотите сохранить все доступные функции на определенной платформе, вы можете запустить GCC следующим образом:
gcc -march=native -dM -E - </dev/null
Это будет сбрасывать макросы типа #define __SSE3__ 1
, #define __AES__ 1
, и т. д.
Если вам нужно кросс-компиляторное решение, просто используйте Boost.Predef
который содержит
BOOST_ARCH_
для архитектуры системы/ЦП, для которой выполняется компиляция.BOOST_COMP_
для используемого компилятора.BOOST_LANG_
для языковых стандартов, против которых ведется компиляция.BOOST_LIB_C_
и BOOST_LIB_STD_ для используемой стандартной библиотеки C и C++.BOOST_OS_
для операционной системы, в которую мы компилируем.BOOST_PLAT_
для платформ поверх операционной системы или компиляторов.BOOST_ENDIAN_
для порядка байтов комбинации операционной системы и архитектуры.BOOST_HW_
для аппаратных особенностей.BOOST_HW_SIMD
для обнаружения SIMD (одна инструкция, несколько данных).
Например
#if defined(BOOST_ARCH_X86)
#if BOOST_ARCH_X86_64
std::cout << "x86_64 " << BOOST_ARCH_X86_64 << " \n";
#elif BOOST_ARCH_X86_32
std::cout << "x86 " << BOOST_ARCH_X86_32 << " \n";
#endif
#elif defined(BOOST_ARCH_ARM)
#if _M_ARM
std::cout << "ARM " << _M_ARM << " \n";
#elif _M_ARM64
std::cout << "ARM64 " << _M_ARM64 << " \n";
#endif
#endif
Вы можете узнать больше о том, как его использовать здесь
Нет ничего стандартного.Брайан Хук задокументировал некоторые из них в своей «Портативной системе с открытым исходным кодом» и даже пытается превратить их во что-то связное и полезное (ymmv по этому поводу).См. заголовок posh.h на этом сайте:
Обратите внимание: ссылка выше может потребовать от вас ввода поддельного идентификатора пользователя/пароля из-за атаки DOS некоторое время назад.
Если вам нужно детальное определение функций ЦП, лучший подход — добавить также программу CPUID, которая выводит на стандартный вывод или в какой-либо файл «cpu_config.h» набор функций, поддерживаемых ЦП.Затем вы интегрируете эту программу в процесс сборки.