Вопрос

Какой самый надежный способ узнать архитектуру ЦП при компиляции кода 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» набор функций, поддерживаемых ЦП.Затем вы интегрируете эту программу в процесс сборки.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top