Определение архитектуры процессора во время компиляции - PullRequest
76 голосов
/ 30 сентября 2008

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

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

Ответы [ 6 ]

73 голосов
/ 30 сентября 2008

Вот некоторая информация о предопределенных макросах архитектуры и других типах предопределенных макросов.

Этот вопрос спрашивает, где они определены в исходном коде GCC.

14 голосов
/ 30 сентября 2008

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

#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?). Просто решите, какие компиляторы будут поддерживать ваше приложение, перечислите их #defines и обновите ваш заголовок по мере необходимости.

5 голосов
/ 04 мая 2016

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

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

Будет сбрасывать макросы типа #define __SSE3__ 1, #define __AES__ 1 и т. Д.

4 голосов
/ 18 октября 2018

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

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

3 голосов
/ 30 сентября 2008

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

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

0 голосов
/ 30 сентября 2008

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

...