مقدمة: لماذا نحتاج لتحليل أداء كود C++؟
التحسين بدون قياس هو مجرد تخمين. حتى المطورون ذوو الخبرة يخطئون غالبًا عند افتراض أي جزء من الكود يعمل بشكل أبطأ. تحليل الأداء هو الطريقة العلمية الوحيدة للإجابة على السؤال: "أين بالضبط يستهلك البرنامج معظم الوقت؟".
في هذه المقالة، سنستعرض الأدوات العملية لتحليل أداء كود C++ على نظام Linux: gprof و perf و Valgrind (Callgrind). ستتعلم كيفية تشغيل محللات الأداء، وتفسير تقاريرها، وإيجاد نقاط الاختناق الحقيقية.
1. تحليل الأداء باستخدام gprof
تحضير الكود
gprof هو أبسط محلل أداء وأكثرها توفرًا. للعمل به، تحتاج إلى ترجمة البرنامج باستخدام العلم -pg:
g++ -pg -O2 main.cpp -o my_programنقوم بتشغيل البرنامج. سيعمل بشكل أبطأ قليلاً من المعتاد، لكنه سينشئ ملف gmon.out الذي يحتوي على بيانات التحليل. ثم نقوم بتشغيل gprof:
./my_programgprof my_program gmon.out > report.txtمثال على التحليل
لننظر إلى برنامج بسيط يحتوي على دالتين:
#include <iostream>#include <cmath>
void slowFunction() { double sum = 0.0; for (int i = 0; i < 100000000; ++i) { sum += std::sin(i) * std::cos(i); } std::cout << "Sum: " << sum << std::endl;}
void fastFunction() { int count = 0; for (int i = 0; i < 1000; ++i) { for (int j = 0; j < 1000; ++j) { count += (i * j) % 3; } } std::cout << "Count: " << count << std::endl;}
int main() { slowFunction(); fastFunction(); return 0;}بعد تشغيل gprof، سنرى في التقرير جدولاً بزمن تنفيذ كل دالة:
Flat profile:
Each sample counts as 0.01 seconds. % cumulative self self total time seconds seconds calls ms/call ms/call name 99.0 1.98 1.98 1 1980.0 1980.0 slowFunction() 1.0 0.02 0.02 1 20.0 20.0 fastFunction()النتيجة واضحة: slowFunction() تستهلك 99% من الوقت. نقطة الاختناق هي استدعاء الدوال المثلثية sin و cos داخل الحلقة.
قيود gprof
- يعمل فقط مع البرامج المترجمة باستخدام
-pg - لا يُظهر الوقت في الدوال المضمنة (inline)
- غير مناسب للتطبيقات متعددة الخيوط (بدون إعدادات إضافية)
2. تحليل الأداء باستخدام perf (Linux)
التشغيل الأساسي
perf هي أداة قوية لتحليل الأداء على مستوى النواة. لا تتطلب إعادة ترجمة البرنامج وتعمل مع أي ملفات ثنائية (حتى مع التحسين -O3):
# التثبيت (إذا لم يكن مثبتًا)sudo apt install linux-tools-common linux-tools-generic
# تحليل الأداء مع حساب دورات المعالجperf stat ./my_program
# تسجيل الأحداث لتحليل مفصلperf record ./my_programperf reportمثال مع perf stat
لنفس البرنامج، سيظهر perf stat:
Performance counter stats for './my_program':
1,987.45 msec task-clock # 1.000 CPUs utilized 10 context-switches # 5.028 /sec 0 cpu-migrations # 0.000 /sec 105 page-faults # 52.832 /sec 5,234,567,890 cycles # 2.634 GHz 9,876,543,210 instructions # 1.89 insn per cycle 1,234,567,890 branches # 621.234 M/sec 10,000,000 branch-misses # 0.81% of all branches
1.987456789 seconds time elapsedالمقاييس الرئيسية