Ответ 1
Вот некоторая информация о предопределенных макросах архитектуры и других типах предопределенных макросов.
Этот вопрос спрашивает, где они определены в исходном коде GCC.
Каков самый надежный способ узнать архитектуру процессора при компиляции кода C или С++? Насколько я могу судить, у разных компиляторов есть собственный набор нестандартных определений препроцессора (_M_X86
в MSVS, __i386__
, __arm__
в GCC и т.д.).
Существует ли стандартный способ определения архитектуры, для которой я строю? Если нет, существует ли источник исчерпывающего списка таких определений для различных компиляторов, таких как заголовок со всем шаблоном #ifdef
s?
Вот некоторая информация о предопределенных макросах архитектуры и других типах предопределенных макросов.
Этот вопрос спрашивает, где они определены в исходном коде GCC.
Нет никакого стандарта между компиляторами, но каждый компилятор имеет тенденцию быть вполне последовательным. Вы можете создать для себя заголовок что-то вроде этого:
#if MSVC
#ifdef _M_X86
#define ARCH_X86
#endif
#endif
#if GCC
#ifdef __i386__
#define ARCH_X86
#endif
#endif
Не так много смысла для всеобъемлющего списка, потому что тысячи компиляторов, но только 3-4 в широком использовании (Microsoft С++, GCC, Intel CC, может быть, TenDRA?). Просто решайте, какие компиляторы будут поддерживать ваше приложение, перечислите их #defines и обновите свой заголовок по мере необходимости.
Если вы хотите сбросить все доступные функции на конкретной платформе, вы можете запустить GCC следующим образом:
gcc -march=native -dM -E - </dev/null
Это #define __SSE3__ 1
бы макросы как #define __SSE3__ 1
, #define __AES__ 1
и т.д.
Нет ничего стандартного. Брайан Хук задокументировал кучу этих данных в своей "Portable Open Source Harness" и даже пытается превратить их в нечто последовательное и полезное (ymmv относительно этого). См. Заголовок posh.h на этом сайте:
Примечание. В приведенной выше ссылке может потребоваться ввести некоторое фиктивное имя пользователя/пароль из-за атаки DOS некоторое время назад.
Если вам нужно решение для кросс-компиляции, просто используйте Boost.Predef
который содержит
BOOST_ARCH_
для архитектуры системы/процессора, для которой выполняется компиляция.BOOST_COMP_
для компилятора, который используется.BOOST_LANG_
для языковых стандартов, которые компилируются.BOOST_LIB_C_
и BOOST_LIB_STD_ для используемой стандартной библиотеки C и C++.BOOST_OS_
для операционной системы, которую мы компилируем.BOOST_PLAT_
для платформ поверх операционной системы или компиляторов.BOOST_ENDIAN_
за BOOST_ENDIAN_
и архитектуры.BOOST_HW_
для аппаратных особенностей.BOOST_HW_SIMD
для 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
Вы можете узнать больше о том, как использовать его здесь
Если вам требуется мелкомасштабное обнаружение функций ЦП, наилучшим подходом является отправка также программы CPUID, которая выводит на stdout или некоторый файл "cpu_config.h" набор функций, поддерживаемых процессором. Затем вы интегрируете эту программу с процессом сборки.