Jaki jest najbardziej niezawodny sposób na poznanie architektury procesora podczas kompilowania kodu w C lub C ++? O ile wiem, różne kompilatory mają swój własny zestaw niestandardowych definicji preprocesorów ( _M_X86
w MSVS __i386__
, __arm__
w GCC itp.).
Czy istnieje standardowy sposób wykrywania architektury, dla której tworzę? Jeśli nie, czy istnieje źródło dla obszernej listy takich definicji dla różnych kompilatorów, na przykład nagłówek ze wszystkimi szablonami #ifdef
?
c++
c
detection
cpu-architecture
compile-time
Alex B.
źródło
źródło
Odpowiedzi:
Oto kilka informacji na temat wstępnie zdefiniowanych makr architektury i innych typów wstępnie zdefiniowanych makr.
To pytanie dotyczy miejsca ich zdefiniowania w kodzie źródłowym GCC.
źródło
Nie ma standardu międzykompilatorowego, ale każdy kompilator jest dość spójny. Możesz zbudować dla siebie nagłówek, który wygląda mniej więcej tak:
#if MSVC #ifdef _M_X86 #define ARCH_X86 #endif #endif #if GCC #ifdef __i386__ #define ARCH_X86 #endif #endif
Pełna lista nie ma większego sensu, ponieważ istnieją tysiące kompilatorów, ale tylko 3-4 w powszechnym użyciu (Microsoft C ++, GCC, Intel CC, może TenDRA?). Po prostu zdecyduj, które kompilatory będzie obsługiwać Twoja aplikacja, podaj ich #defines i zaktualizuj nagłówek zgodnie z potrzebami.
źródło
_M_X86
pozytywnie nie zostało zdefiniowane (kompilacja 32-bitowa). Prawidłowy to_M_IX86
(dzięki powyższemu linkowi Serge'a).Jeśli chcesz zrzucić wszystkie dostępne funkcje na określonej platformie, możesz uruchomić GCC w ten sposób:
gcc -march=native -dM -E - </dev/null
Byłoby zrzucić jak makra
#define __SSE3__ 1
,#define __AES__ 1
itpźródło
-march=native
nie działa dla ARM i MIPS dla GCC 4.9 i starszych.Jeśli potrzebujesz rozwiązania obejmującego wiele kompilatorów, po prostu użyj,
Boost.Predef
który zawieraBOOST_ARCH_
dla architektury systemu / procesora, dla której jest kompilowany.BOOST_COMP_
dla kompilatora, którego używa.BOOST_LANG_
dla standardów językowych, przeciwko którym się kompiluje.BOOST_LIB_C_
i BOOST_LIB_STD_ dla używanej standardowej biblioteki C i C ++.BOOST_OS_
dla systemu operacyjnego, do którego kompilujemy.BOOST_PLAT_
na platformy oparte na systemie operacyjnym lub kompilatorach.BOOST_ENDIAN_
dla endianness kombinacji systemu operacyjnego i architektury.BOOST_HW_
dla funkcji specyficznych dla sprzętu.BOOST_HW_SIMD
do wykrywania SIMD (Single Instruction Multiple Data).Na przykład
#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
Możesz dowiedzieć się więcej o tym, jak go używać tutaj
źródło
Nie ma nic standardowego. Brian Hook udokumentował kilka z nich w swojej „Portable Open Source Harness”, a nawet próbuje uczynić z nich coś spójnego i użytecznego (ymmv odnośnie tego). Zobacz nagłówek posh.h na tej stronie:
Uwaga, powyższy link może wymagać wprowadzenia fałszywego identyfikatora użytkownika / hasła z powodu ataku DOS jakiś czas temu.
źródło
Jeśli potrzebujesz dokładnego wykrywania funkcji procesora, najlepszym rozwiązaniem jest dostarczenie również programu CPUID, który wysyła do standardowego wyjścia lub jakiegoś pliku „cpu_config.h” zestaw funkcji obsługiwanych przez procesor. Następnie integrujesz ten program z procesem kompilacji.
źródło