- أساس التحسين الجيد في لغة C/C++ هو الجمع بين العناصر بشكل منطقي.
-marchالمستويات-Oوبعض الخيارات الآمنة مثل-pipe. - يمكن للتقنيات المتقدمة مثل LTO و PGO و OpenMP أو Graphite أن توفر تحسينات كبيرة، لكنها تزيد من تعقيد عملية التجميع والتصحيح.
- تعمل علامات التحصين (FORTIFY، حماية المكدس، PIE، relro/now) على تعزيز الأمان مقابل بعض فقدان الأداء.
- تتيح لك CMake والمولدات المختلفة الحفاظ على التعليمات البرمجية القابلة للنقل عبر GCC و Clang و MSVC ومنصات مختلفة دون لمس التعليمات البرمجية المصدرية.
عندما تبدأ اللعب مع خيارات التجميع في لغتي C و C++ من السهل الوقوع في إغراء تفعيل جميع الخيارات "الرائعة" التي تراها على الإنترنت. لكن الحقيقة هي أن مزيجًا سيئًا من هذه الخيارات قد يجعل نظامك غير مستقر، أو يُعطّل عمليات البناء، أو ما هو أسوأ، يُنتج ملفات تنفيذية تفشل بطرق خفية للغاية أو تتطلب استخراج معلومات؛ في هذه الحالات، قد يكون ذلك مفيدًا. استخراج النص المخفي في الملفات الثنائية للتحقيق.
يهدف هذا الدليل إلى مساعدتك على فهم كيفية القيام بذلك بطريقة عملية ومباشرة. تحسين الملفات الثنائية في لغة C/C++ باستخدام GCC و Clang باستخدام الخيارات الصحيحة: من الخيارات الكلاسيكية -O2, -march y -pipe...إلى تقنيات متقدمة مثل LTO وPGO وOpenMP وGraphite وتعزيز الأمان. ستتعرف أيضًا على كيفية تكامل كل هذا مع CMake وMinGW/MSYS2 وVisual Studio وXcode أو Ninja لبناء بيئة قابلة للنقل والصيانة.
ما هي CFLAGS و CXXFLAGS وكيف يتم استخدامها دون إحداث أي مشاكل؟
في جميع أنواع الأنظمة تقريباً يونكس (لينكس(مثل BSD، إلخ.) يتم استخدام المتغيرات CFLAGS y CXXFLAGS لتمرير الخيارات بالنسبة لمترجمي لغتي C و C++. لا تُعدّ هذه القواعد جزءًا من أي معيار رسمي، ولكنها شائعة لدرجة أن أي نظام بناء جيد (مثل Make و Autotools و CMake و Meson...) يحترمها.
في توزيعات مثل جنتو، يتم تعريف هذه المتغيرات بشكل عام في /etc/portage/make.confومن ثم، يتم توريثها لجميع الحزم المُجمَّعة باستخدام Portage. أما في الأنظمة الأخرى، فيمكنك تصديرها من سطر الأوامر أو وضعها في... Makefileل سيناريو من CMake أو ما شابه.
من الشائع جدًا تعريف CXXFLAGS إعادة استخدام محتوى CFLAGS وإذا لزم الأمر، أضف أي خيارات محددة للغة C++. على سبيل المثال: CXXFLAGS="${CFLAGS} -fno-exceptions"الشيء المهم هو عدم إضافة العلامات بشكل عشوائي هناك، لأنها ستُطبق على كل شيء تقوم بتجميعه.
ومن المهم أن يكون واضحا أن قد تؤدي الخيارات العدوانية في CFLAGS/CXXFLAGS إلى تعطيل عمليات البناءقد يؤدي ذلك إلى ظهور أخطاء يصعب تصحيحها، أو حتى إبطاء عمل البرامج. ولا تُفضي المستويات العالية من التحسين دائمًا إلى أداء أفضل، وقد تستغل بعض التحويلات افتراضات لا يفي بها الكود الخاص بك.
التحسين الأساسي: -march و -mtune و -O levels
يرتكز أي تعديل معقول على ثلاثة عناصر: حدد بنية وحدة المعالجة المركزية، واختر مستوى التحسين، وقم أحيانًا بتفعيل تحسينات صغيرة وغير ضارة. كما -pipeكل شيء آخر تقريباً سيأتي لاحقاً، وبذهن صافٍ.
اختيار البنية: -مارش، -إم تيون وشركاؤهما
الخيار -march=<cpu> يُخبر GCC/Clang بعائلة المعالج المحددة سوف إنشاء التعليمات البرمجيةيُتيح ذلك استخدام تعليمات مُحددة (مثل SSE وAVX وAVX2 وAVX-512 وغيرها) وإجراء تعديلات على واجهة التطبيق الثنائية (ABI). إذا اخترتَ معالجًا حديثًا جدًا، فلن يعمل البرنامج على الأجهزة القديمة.
لمعرفة ما يدعمه معالجك، يمكنك الرجوع إلى نظام لينكس. /proc/cpuinfo أو الاستخدام الأوامر من مُجمِّع الأنماط نفسه gcc -Q -O2 --help=targetفي أنظمة x86-64 الحديثة، تم توحيد الملفات التعريفية العامة مثل: x86-64-v2, x86-64-v3 y x86-64-v4أي مجموعة من مجموعات التعليمات المتزايدة والتي تم دعمها منذ GCC 11.
زائد -march، موجود -mtune=<cpu> لـ "ضبط" التخطيط من الكود إلى نموذج محدد دون استخدام تعليمات جديدة. كما أنها تظهر في معمارية غير x86 -mcpu y -mtune تشمل الخيارات ذات الصلة (ARM، وPowerPC، وSPARC...). في x86، -mcpu إنها في الواقع قديمة الطراز.
إحدى الحيل الشائعة الاستخدام هي -march=nativeيُمكّن هذا المُصرّف من اكتشاف وحدة المعالجة المركزية للجهاز المحلي وتفعيل الإضافات المناسبة تلقائيًا. يُعدّ هذا مثاليًا في البيئات التي تُشغّل فيها الملفات التنفيذية على نفس الجهاز الذي تُصرّفها عليه فقط، ولكنه يُشكّل خطرًا كبيرًا عند إنشاء حزم لوحدات معالجة مركزية أخرى.
في المعالجات الحديثة لـ إنتل وتستخدم AMD وGCC أسماءً محددة لكل عائلة، مثل -march=rocketlake, -march=sapphirerapids, -march=znver2 o -march=znver3تجمع هذه الخيارات التعليمات المتقدمة (AVX2، AVX-512، FMA، إلخ) لكل جيل وتتيح لك الاستفادة بشكل كبير من خردوات عندما تعرف أين ستنشر قواتك.
مستويات التحسين -O: متى يُستخدم كل مستوى
الخيار -O يتحكم في المستوى العام للتحسين يتم تطبيقها على الكود. كل خطوة تُفعّل مجموعة أوسع من التحويلات، مما يؤثر على كل من وقت التجميع واستهلاك الذاكرة وسهولة تصحيح الأخطاء.
-O0غير مُحسَّن. هذا هو الخيار الافتراضي في حال عدم تحديد أي شيء. يتم تجميعه بسرعة ويُنتج كودًا يسهل تصحيحه، ولكنه بطيء وكبير الحجم. مثالي لمراحل التطوير المبكرة واستكشاف الأخطاء المعقدة.-O1المستوى الأول من التحسين. يطبق تحسينات غير مكلفة نسبياً توفر عادةً دفعة أداء جيدة دون أن تجعل عملية التجميع ثقيلة للغاية.-O2: هو المستوى الموصى به للاستخدام العام في معظم المشاريع. إنه يحقق توازناً جيداً بين الأداء ووقت التجميع والاستقرار.ولهذا السبب فهي القيمة التي تستخدمها العديد من التوزيعات بشكل افتراضي.-O3: يُفعّل جميع تحسينات-O2تتضمن بعض التحويلات الأكثر قوةً فكّ الحلقات بشكل مكثف أو استخدام تقنيات التوجيه المتجهي بشكل أكبر. قد يكون هذا فعالاً في بعض الأكواد الرقمية، ولكنه يزيد من احتمالية اكتشاف سلوك غير محدد في الكود أو زيادة حجم الملف التنفيذي.-Osتهدف هذه الطريقة إلى تقليل حجم الملف الثنائي من خلال إعطاء الأولوية للمساحة على السرعة. وهي مفيدة في البيئات ذات تخزين أو ذاكرة تخزين مؤقتة محدودة للغاية.-Oz(GCC 12+): يُحقق هذا الخيار توفيرًا كبيرًا في الحجم، مع قبول انخفاضات ملحوظة في الأداء. وهو مفيد للملفات الثنائية الصغيرة جدًا أو في حالات محددة للغاية.-Ofastيشبه الأمر-O3لا يلتزم هذا الأسلوب بمعايير لغة C/C++ بشكلٍ صارم. فهو يسمح لك بتجاوز بعض ضمانات اللغة لتحسين الأداء، خاصةً في حسابات الفاصلة العائمة. لذا، يجب عليك استخدامه بفهمٍ كامل لما تقوم به.-Ogمصمم لأغراض تصحيح الأخطاء. فهو لا يطبق سوى التحسينات التي لا تتعارض بشكل كبير مع مصحح الأخطاء، ويترك الكود في نقطة وسطية بين-O0y-O1.
مستويات أعلى -O3 كما -O4 o -O9 كلها مجرد خداع بصرييقبلها المترجم ولكنه يعاملها داخليًا على أنها -O3لا يوجد سحر خفي هناك، مجرد تظاهر.
إذا بدأت تلاحظ عمليات بناء تفشل بشكل غامض، أو أعطال غريبة، أو نتائج مختلفة اعتمادًا على المُحسِّن، فإن الخطوة التشخيصية الجيدة هي ينخفض مؤقتًا إلى -O1 س incluso -O0 -g2 -ggdb للحصول على ملفات ثنائية يسهل تصحيحها والإبلاغ عن الخطأ بمعلومات مفيدة.
- الأنابيب وخيارات أساسية أخرى
العلم -pipe يُخبر المُترجم باستخدام الأنابيب في الذاكرة بدلاً من استخدام الملفات المؤقتة على القرص بين مراحل الترجمة (المعالجة المسبقة، الترجمة، التجميع). عادةً ما يُسرّع هذا الأسلوب العملية نوعًا ما، على الرغم من أنه يستهلك المزيد من ذاكرة الوصول العشوائي (RAM). في الأجهزة ذات الذاكرة المحدودة جدًا، قد يتسبب ذلك في تعطل المُترجم، لذا يُنصح باستخدامه باعتدال في هذه الحالات.
خيارات تقليدية أخرى مثل -fomit-frame-pointer تتيح لك هذه الخاصية تحرير سجل مؤشر المكدس لتوليد المزيد من التعليمات البرمجية، لكنها تُصعّب عملية تصحيح الأخطاء مع الحصول على تتبعات خلفية واضحة. في معمارية x86-64 الحديثة، يتعامل المُصرّف مع هذا الأمر بكفاءة عالية، وغالبًا لا يكون من الضروري ضبطه يدويًا.
امتدادات SIMD، وجرافيت، وتحويل الحلقات إلى متجهات
تُمكّن المترجمات الحديثة لأنظمة x86-64 تلقائيًا العديد من تعليمات SIMD اعتمادًا على وحدة المعالجة المركزية المختارة. -marchومع ذلك، سترى أعلامًا مثل -msse2, -mavx2 أو ما شابهها التي يمكن إضافتها بشكل صريح.
بشكل عام، إذا كنت تستخدم -march هذا مناسب؛ لست بحاجة إلى تفعيله يدويًا. -msse, -msse2, -msse3, -mmmx o -m3dnowلأنها مُفعّلة افتراضيًا. ولا يُجدي نفعًا فرضها إلا على معالجات محددة جدًا حيث لا يُفعّلها مُجمّع GCC/Clang افتراضيًا.
بالنسبة للحلقات المعقدة، تتضمن GCC مجموعة من التحسينات الجرافيتوالتي تعتمد على مكتبة ISL. من خلال علامات مثل -ftree-loop-linear, -floop-strip-mine y -floop-block يقوم المترجم بتحليل الحلقات ويمكنه إعادة هيكلتها لتحسين موضع البيانات والتوازي؛ للاطلاع على حالات محددة، انظر أمثلة على لغة C منخفضة المستوى يساعد ذلك في تكييف الكود لهذه التحويلات.
يمكن أن تُسفر هذه التحويلات عن نتائج جيدة في البرامج الرقمية المعقدة، ولكن لم يكونوا غير مؤذيينقد تؤدي هذه الميزات إلى زيادة استهلاك ذاكرة الوصول العشوائي (RAM) بشكل ملحوظ أثناء عملية التجميع، وقد تتسبب في أعطال في المشاريع الكبيرة التي لم تُصمم مع مراعاة هذه الميزات. لذا، يُنصح بتفعيلها فقط في أجزاء محددة من التعليمات البرمجية أو في مشاريع تم اختبارها والتأكد من عملها بشكل صحيح.
التوازي: OpenMP، و-fopenmp، و-ftree-parallelize-loops
إذا كان الكود الخاص بك يستخدم برنامج OpenMPيوفر كل من GCC و Clang دعمًا قويًا إلى حد ما من خلال الخيار -fopenmpيسمح هذا بتوازي أجزاء من التعليمات البرمجية، وخاصة الحلقات، باستخدام التوجيهات في التعليمات البرمجية المصدرية نفسها، وللمترجم بإنشاء العمل في خيوط متعددة.
زائد -fopenmpيتضمن نظام التحكم في الجر (GCC) الخيار -ftree-parallelize-loops=Nحيث N يتم ضبطه عادةً على عدد النوى المتاحة (على سبيل المثال باستخدام $(nproc) (في نصوص البناء). تحاول هذه الطريقة تنفيذ الحلقات بالتوازي تلقائيًا دون الحاجة إلى إضافة توجيهات يدوية، على الرغم من أن النجاح يعتمد بشكل كبير على كيفية كتابة الكود.
نضع في اعتبارنا أن قد يكون تفعيل OpenMP على مستوى النظام بأكمله أمراً إشكالياً للغاية.بعض المشاريع غير مستعدة لذلك، والبعض الآخر يستخدم نماذج التزامن الخاصة به، والبعض الآخر يفشل ببساطة في التجميع عند مواجهته. -fopenmpالشيء المنطقي الذي يجب فعله هو تمكينه لكل مشروع أو حتى لكل وحدة، وليس في CFLAGS العامة للنظام.
تحسين وقت الربط: LTO
La تحسين وقت الربط (LTO) يسمح ذلك للمترجم بعدم الاقتصار على ملف مصدر واحد عند التحسين، بل برؤية البرنامج بأكمله في مرحلة الربط وتطبيق التحسينات العالمية على جميع الكائنات المعنية.
في نظام التحكم في الخليج، يتم تفعيله باستخدام -fltoويمكن تحديد عدد من الخيوط، على سبيل المثال -flto=4أو دعه يكتشف عدد النوى باستخدام -flto=autoإذا تم استخدامه أيضًا -fuse-linker-plugin بالإضافة إلى الرابط الذهب وبفضل تثبيت المكون الإضافي LTO في binutils، يمكن للمترجم استخراج معلومات LTO حتى من المكتبات الثابتة المشاركة في الربط.
عادةً ما يتم توليد LTO ملفات تنفيذية أصغر حجماً، وفي كثير من الحالات أسرع.لأنه يقضي على التعليمات البرمجية غير المستخدمة ويسمح بالتضمين المباشر بين الوحدات. في المقابل، تيمبو ترتفع أوقات التجميع واستهلاك الذاكرة بشكل كبير، خاصة في المشاريع الكبيرة التي تحتوي على آلاف ملفات الكائنات.
في بيئات مثل Gentoo، حيث يتم إعادة تجميع النظام بأكمله من المصدر، لا يزال تطبيق LTO على مستوى العالم يعتبر مسألة حساسة: هناك العديد من الحزم التي لا تزال لا تعمل بشكل جيد مع LTO. ويتطلب ذلك تعطيله بشكل انتقائي. ولهذا السبب يُنصح عادةً بتفعيله فقط في مشاريع محددة أو إصدارات GCC/Clang حيث تكون الفائدة ملحوظة حقًا.
PGO: التحسين الموجه بالملف الشخصي
La التحسين الموجه بالملف الشخصي (PGO) يتكون من تجميع البرنامج مرة واحدة مع أدوات القياس، وتشغيله بأحمال عمل تمثيلية لجمع إحصائيات التنفيذ، ثم إعادة تجميعه باستخدام تلك الملفات التعريفية لتوجيه المُحسِّن.
في دول مجلس التعاون الخليجي، يكون التدفق النموذجي كما يلي: قم بالتجميع أولاً باستخدام -fprofile-generateقم بتشغيل البرنامج (أو اختباراته) لإنشاء بيانات الملف الشخصي، ثم التوافق مع -fprofile-use يشير إلى المجلد الذي تُخزَّن فيه ملفات التعريف. مع خيارات إضافية مثل -fprofile-correction أو عن طريق تعطيل بعض الإشعارات (-Wno-error=coverage-mismatchيمكن تجنب الأخطاء المتكررة الناتجة عن تغييرات التعليمات البرمجية بين المراحل؛ كما أنها مفيدة عادةً مراقبة الأداء باستخدام eBPF و perf للحصول على ملفات تعريف دقيقة.
عند تطبيقها بشكل صحيح، يمكن لـ PGO توفر تحسينات في الأداء تتجاوز بكثير مجرد زيادة مستوى -Oلأنه يتخذ القرارات بناءً على بيانات تنفيذ واقعية، وليس على نماذج عامة. تكمن المشكلة في أن هذه العملية معقدة: إذ يجب تكرارها مع كل تحديث ذي صلة للبرنامج، وتعتمد بشكل كبير على أن يكون سيناريو الاختبار ممثلاً للاستخدام الفعلي.
بعض المشاريع (بما في ذلك GCC نفسه في بعض التوزيعات) تقدم بالفعل أعلام أو نصوص برمجية محددة لتفعيل PGO تلقائيًا، ولكن بشكل عام تظل هذه التقنية مخصصة للمستخدمين المتقدمين الذين يرغبون في استثمار الوقت في هذه العملية.
تعزيز الأمان: الأمان القائم على العلامات
إلى جانب السرعة، تركز العديد من بيئات التطوير على تحصين البرامج الثنائية ضد الثغرات الأمنية، حتى لو كان ذلك على حساب بعض التضحيات في الأداء. يوفر GCC والروابط الحديثة نطاقًا جيدًا من خيارات التقوية والتي يمكن تفعيلها من CFLAGS/CXXFLAGS و LDFLAGS.
بعض من أكثرها شيوعا هي:
-D_FORTIFY_SOURCE=2o=3: يضيف فحوصات إضافية على وظائف معينة في مكتبة libc لاكتشاف تجاوزات المخزن المؤقت في وقت التشغيل.-D_GLIBCXX_ASSERTIONS: يقوم بتفعيل عمليات التحقق من الحدود على الحاويات وسلاسل C++ في مكتبة STL، ويكتشف عمليات الوصول خارج النطاق.-fstack-protector-strong: يقوم بإدخال بيانات الكناري في المكدس لاكتشاف عمليات الكتابة التي تؤدي إلى تلفه.-fstack-clash-protection: يخفف من حدة الهجمات القائمة على التصادمات بين المكدس ومناطق الذاكرة الأخرى.-fcf-protection: يضيف حماية لتدفق التحكم (على سبيل المثال، ضد هجمات ROP) على البنى التي تدعمها.-fpieمع-Wl,-pie: يقوم بإنشاء ملفات تنفيذية قابلة للتحديد الموضعي، وهو أمر ضروري لتقنية ASLR الفعالة.-Wl,-z,relroy-Wl,-z,nowتعمل هذه الإجراءات على تقوية جدول النقل وتعطيل الربط الكسول لـ رموزإعاقة بعض أساليب الهجوم.
تتضمن الملفات الشخصية "المحصنة" لبعض التوزيعات بالفعل العديد من هذه الخيارات مفعلة بشكل افتراضي. قد يؤدي تفعيلها يدويًا دون فهم التأثير إلى تباطؤ ملحوظ في أداء الملفات الثنائية.، خاصة في التطبيقات الكبيرة أو التي تستهلك الكثير من الذاكرة، ولكن على الخوادم المكشوفة أو أجهزة الكمبيوتر المكتبية الحساسة، عادة ما يكون سعره معقولاً.
اختر المُصرّف والبيئة: GCC، Clang، MSVC، MinGW، Xcode…
في الواقع، غالباً لا يقتصر الأمر على اختيار الأعلام فحسب، بل ما هو المترجم وما هي سلسلة الأدوات الكاملة التي ستستخدمها؟ على كل منصة. عادةً ما يكون أداء GCC وClang متشابهًا جدًا، وتكون الاختلافات أكثر وضوحًا في التشخيص، وأوقات التجميع، أو التوافق مع بعض الإضافات.
En ويندوز أمامك عدة مسارات: فيجوال ستوديو (MSVC) بمجموعات أدواتهم v143, v142إلخ؛ أو مينغو-w64 من خلال MSYS2 مما يوفر لك نظامي التشغيل Windows GCC وClang الأصليين بالإضافة إلى مكتبات Win32 اللازمة. تتم إدارة MSYS2 بواسطة pacman ويوفر بيئات MinGW64 (المستندة إلى MSVCRT الكلاسيكية) و UCRT64 (مع Universal CRT، وهو أكثر حداثة).
في نظام macOS، المسار القياسي هو كسكودي مع clang/clang++، حيث المفهوم الأساسي هو مجموعة تطوير البرامج الأساسية (SDK) (إصدار النظام الذي تم تجميعه من أجله) و هدف النشر (أدنى إصدار من نظام macOS الذي ترغب في تشغيل تطبيقك عليه). يؤدي ضبط هذا الزوج بشكل صحيح إلى تجنب الكارثة الشائعة المتمثلة في التجميع فقط لأحدث إصدار من النظام، مما يؤدي إلى فشل تشغيل ملفاتك التنفيذية على الإصدارات الأقدم قليلاً.
في نظام لينكس، الشيء الطبيعي الذي يجب فعله هو استخدام جي سي سي وصنع أو نينجاربما باستخدام CMake كمولد بيانات وصفية. بالإضافة إلى ذلك، تسمح لك توزيعات مثل أوبونتو بتثبيت إصدارات متعددة من GCC واختيارها باستخدام update-alternatives، على غرار كيفية استخدامه في نظام macOS xcode-select للتبديل من Xcode.
إذا كنت بحاجة إلى بيئات تصحيح أخطاء مريحة للمشاريع التي تم إنشاؤها باستخدام Make أو Ninja (والتي تتميز بتكوين واحد)، كسوف CDT y كود الاستوديو المرئي هذان خياران مفيدان للغاية: يمكن لـ CMake إنتاج ملفات المشروع التي تحتاجها أو التكامل معها مباشرة لتكوينها وتجميعها وتصحيح أخطائها.
قابلية النقل وCMake: نفس الكود، سلاسل أدوات مختلفة
يتطلب الحصول على مشروع C/C++ ليتم تجميعه دون لمس الكود على أنظمة Windows وLinux وmacOS مزيجًا جيدًا من كليهما. CMake، والمولدات المتاحة، والمترجمات المختلفةالفكرة هي أن الملف CMakeLists.txt صف المشروع بطريقة مجردة وسيقوم CMake بإنشاء نوع المشروع المناسب على كل منصة.
في نظام ويندوز، يمكنك استدعاء CMake باستخدام -G "Visual Studio 17 2022" لإنتاج حل باستخدام msbuild، أو باستخدام -G "Ninja" للحصول على عمليات بناء أسرع من وحدة التحكم. بالإضافة إلى ذلك، من خلال -T v143, v142إلخ، يمكنك تحديد مجموعة أدوات النظام الأساسي (إصدار مُصرّف MSVC) ومع -A x64, Win32 o arm64 أنت من يختار التصميم المعماري.
مع MinGW/MSYS2، فإن الشيء الطبيعي الذي يجب استخدامه هو -G "MinGW Makefiles" o -G "Ninja" ومن خلال المتغيرات CMAKE_C_COMPILER y CMAKE_CXX_COMPILERاختر ما إذا كنت تريد استخدام GCC أو Clang. في هذه الحالة، يتم التحكم في الإعدادات (التصحيح، الإصدار، إلخ) عبر -DCMAKE_BUILD_TYPE، لأن Make و Ninja عبارة عن تكوين واحد.
على macOS ، -G Xcode يوفر لك مشروعًا مثاليًا لتصحيح الأخطاء في بيئة التطوير المتكاملة، ويمكنك التحكم في حزمة تطوير البرامج (SDK) وهدف النشر باستخدام متغيرات مثل CMAKE_OSX_DEPLOYMENT_TARGETإذا كنت تريد فقط Make أو Ninja، فستستخدم نفس المولدات المستخدمة في Linux.
يكمن جمال كل هذا في أنه، عند إعداده بشكل صحيح، يمكنك الحفاظ على قاعدة بيانات واحدة ومجموعة متسقة من الخيارات (قد تكون خاصة بمنصة معينة) والتجميع في أي بيئة دون الحاجة إلى تعديل الكود المصدري باستمرار. ومع ذلك، من المهم تذكر المبدأ الأساسي: أولاً، تأكد من أنه يعمل بشكل صحيح، ثم سنقوم بتسريع عملية التحسين..
بعد كل ما تم الاطلاع عليه، فإن الفكرة العامة هي التمسك بـ مزيج معتدل ولكنه فعال (شيء من هذا القبيل) -O2 -march=<cpu adecuada> -pipe بالإضافة إلى بعض التحسينات المعقولة) والاحتفاظ بالأسلحة الكبيرة - LTO و PGO و Graphite و OpenMP العدواني - لتلك المشاريع أو الوحدات التي يتم فيها قياس التحسينات حقًا ويتم قبول تكاليف الصيانة وتصحيح الأخطاء التي تجلبها.
كاتب شغوف بعالم البايت والتكنولوجيا بشكل عام. أحب مشاركة معرفتي من خلال الكتابة، وهذا ما سأفعله في هذه المدونة، لأعرض لك كل الأشياء الأكثر إثارة للاهتمام حول الأدوات الذكية والبرامج والأجهزة والاتجاهات التكنولوجية والمزيد. هدفي هو مساعدتك على التنقل في العالم الرقمي بطريقة بسيطة ومسلية.