Обнаружение времени компиляции архитектуры процессора

Каков самый надежный способ узнать архитектуру процессора при компиляции кода C или С++? Насколько я могу судить, у разных компиляторов есть собственный набор нестандартных определений препроцессора (_M_X86 в MSVS, __i386__, __arm__ в GCC и т.д.).

Существует ли стандартный способ определения архитектуры, для которой я строю? Если нет, существует ли источник исчерпывающего списка таких определений для различных компиляторов, таких как заголовок со всем шаблоном #ifdef s?

Ответ 2

Нет никакого стандарта между компиляторами, но каждый компилятор имеет тенденцию быть вполне последовательным. Вы можете создать для себя заголовок что-то вроде этого:

#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 и обновите свой заголовок по мере необходимости.

Ответ 3

Если вы хотите сбросить все доступные функции на конкретной платформе, вы можете запустить GCC следующим образом:

gcc -march=native -dM -E - </dev/null

Это #define __SSE3__ 1 бы макросы как #define __SSE3__ 1, #define __AES__ 1 и т.д.

Ответ 4

Нет ничего стандартного. Брайан Хук задокументировал кучу этих данных в своей "Portable Open Source Harness" и даже пытается превратить их в нечто последовательное и полезное (ymmv относительно этого). См. Заголовок posh.h на этом сайте:

Примечание. В приведенной выше ссылке может потребоваться ввести некоторое фиктивное имя пользователя/пароль из-за атаки DOS некоторое время назад.

Ответ 5

Если вам нужно решение для кросс-компиляции, просто используйте 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

Вы можете узнать больше о том, как использовать его здесь

Ответ 6

Если вам требуется мелкомасштабное обнаружение функций ЦП, наилучшим подходом является отправка также программы CPUID, которая выводит на stdout или некоторый файл "cpu_config.h" набор функций, поддерживаемых процессором. Затем вы интегрируете эту программу с процессом сборки.