الكشف عن وقت تجميع بنية وحدة المعالجة المركزية
-
02-07-2019 - |
سؤال
ما هي الطريقة الأكثر موثوقية لاكتشاف بنية وحدة المعالجة المركزية عند تجميع كود C أو C++؟بقدر ما أستطيع أن أقول، المترجمون المختلفون لديهم مجموعة خاصة بهم من تعريفات المعالج المسبق غير القياسية (_M_X86
في إم إس في إس، __i386__
, __arm__
في دول مجلس التعاون الخليجي وغيرها).
هل يوجد معيار طريقة للكشف عن العمارة التي أقوم بالبناء من أجلها؟إذا لم يكن الأمر كذلك، فهل هناك مصدر لقائمة شاملة من هذه التعريفات لمختلف المترجمين، مثل رأس يحتوي على جميع المعايير #ifdef
س؟
المحلول
وهنا بعض المعلومات حول وحدات الماكرو المعمارية المحددة مسبقًا وأنواع أخرى من وحدات الماكرو المحددة مسبقًا.
هذا السؤال يسأل أين يتم تعريفهم في كود المصدر لدول مجلس التعاون الخليجي.
نصائح أخرى
لا يوجد معيار مشترك بين المترجمات، لكن كل مترجم يميل إلى أن يكون متسقًا تمامًا.يمكنك إنشاء رأس لنفسك يشبه هذا:
#if MSVC
#ifdef _M_X86
#define ARCH_X86
#endif
#endif
#if GCC
#ifdef __i386__
#define ARCH_X86
#endif
#endif
ليس هناك فائدة كبيرة من وضع قائمة شاملة، لأن هناك الآلاف من المترجمين ولكن 3-4 منها فقط تستخدم على نطاق واسع (Microsoft C++، وGC، وIntel CC، وربما TenDRA؟).ما عليك سوى تحديد المترجمين الذين سيدعمهم تطبيقك، وإدراج #تعريفاتهم، وتحديث رأسك حسب الحاجة.
إذا كنت ترغب في تفريغ كافة الميزات المتوفرة على نظام أساسي معين، فيمكنك تشغيل دول مجلس التعاون الخليجي مثل:
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_
من أجل endianness من نظام التشغيل والجمع بين الهندسة المعمارية.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
يمكنك معرفة المزيد عن كيفية استخدامه هنا
لا يوجد شيء قياسي.قام برايان هوك بتوثيق مجموعة من هذه الأشياء في كتابه "Portable Open Source Harness"، بل ويحاول تحويلها إلى شيء متماسك وقابل للاستخدام (ymmv بخصوص ذلك).شاهد رأس posh.h على هذا الموقع:
لاحظ أن الرابط أعلاه قد يطلب منك إدخال معرف مستخدم/كلمة مرور زائفة بسبب هجوم DOS منذ بعض الوقت.
إذا كنت بحاجة إلى اكتشاف دقيق لميزات وحدة المعالجة المركزية، فإن أفضل طريقة هي إرسال برنامج CPUID أيضًا والذي يقوم بإخراج مجموعة الميزات التي تدعمها وحدة المعالجة المركزية إلى ملف stdout أو ملف "cpu_config.h".ثم تقوم بدمج هذا البرنامج مع عملية الإنشاء الخاصة بك.