| PERF-REPORT(1) | perf Manual | PERF-REPORT(1) |
نام (NAME)
perf-report - خواندن perf.data (ایجاد شده توسط perf record) و نمایش پروفایل
خلاصه دستور (SYNOPSIS)
perf report [-i <file> | --input=file]
توضیحات (DESCRIPTION)
این دستور اطلاعات پروفایل شمارندههای کارایی ثبتشده توسط perf record را نمایش میدهد.
گزینهها (OPTIONS)
-i, --input=
-v, --verbose
-q, --quiet
-n, --show-nr-samples
--show-cpu-utilization
-T, --threads
-c, --comms=
--pid=
--tid=
-d, --dsos=
-S, --symbols=
--symbol-filter=
-U, --hide-unresolved
--parallelism
--latency
-s, --sort=
هر کلید معنای زیر را دارد:
بهطور پیشفرض، کلیدهای overhead، comm، dso و symbol استفاده میشوند. (یعنی --sort overhead,comm,dso,symbol).
اگر گزینه --branch-stack استفاده شود، کلیدهای مرتبسازی زیر نیز در دسترس خواهند بود:
و کلیدهای مرتبسازی پیشفرض به comm، dso_from، symbol_from، dso_to و symbol_to تغییر مییابند؛ گزینه '--branch-stack' را ببینید.
هنگامی که کلید مرتبسازی symbol مشخص شود، ستونهای "IPC" و "IPC Coverage" بهطور خودکار فعال میشوند. ستون "IPC" میانگین IPC به ازای هر تابع را گزارش میدهد و ستون "IPC coverage" درصد دستورالعملهای دارای IPC نمونهبرداریشده در این تابع را گزارش میکند. منظور از IPC تعداد دستورالعمل بر چرخه (Instruction Per Cycle) است. پایین بودن آن نشاندهنده احتمال وجود یک گلوگاه عملکردی در هنگام اجرای تابع است، مانند گلوگاه دسترسی به حافظه. چنانچه تابعی دارای سربار بالا و IPC پایین باشد، ارزش بررسی بیشتر جهت بهینهسازی کارایی را دارد.
در صورت استفاده از گزینه --mem-mode، کلیدهای مرتبسازی زیر نیز در دسترس خواهند بود (ناسازگار با --branch-stack): symbol_daddr، dso_daddr، locked، tlb، mem، snoop، dcacheline، blocked.
و کلیدهای مرتبسازی پیشفرض به local_weight، mem، sym، dso، symbol_daddr، dso_daddr، snoop، tlb، locked، blocked، local_ins_lat تغییر مییابند، '--mem-mode' را ببینید.
اگر فایل داده دارای رویداد(های) tracepoint باشد، کلیدهای مرتبسازی (پویای) زیر نیز در دسترس خواهند بود: trace, trace_fields, [<event>.]<field>[/raw]
حالت آخر از نامهای رویداد و فیلد تشکیل شده است. اگر نام رویداد حذف شود، تمام رویدادها را برای پیدا کردن نام فیلد منطبق جستجو میکند. فیلد منطبق فقط برای رویدادی که دارای آن فیلد است نمایش داده خواهد شد. نام رویداد از تطابق زیررشته پشتیبانی میکند بنابراین نیازی نیست کاربر هر بار نام کامل زیرسیستم و رویداد را مشخص کند. برای مثال، رویداد 'sched:sched_switch' تا زمانی که مبهم نباشد میتواند به 'switch' کوتاه شود. همچنین رویداد میتواند با نمایهاش (شروع از ۱) با پیشوند '%' مشخص شود. بنابراین '%1' رویداد اول، '%2' رویداد دوم و الی آخر است.
نام فیلد میتواند پسوند '/raw' داشته باشد که چاپ خوانا را غیرفعال کرده و مقدار خام فیلد را مانند اعداد هگزادسیمال نمایش میدهد. گزینه --raw-trace اثری مشابه برای تمام کلیدهای مرتبسازی پویا دارد.
اگر همه رویدادها در فایل داده از نوع tracepoint باشند، کلیدهای مرتبسازی پیشفرض به 'trace' تغییر مییابند.
-F, --fields=
همچنین میتواند شامل هر کلید(های) مرتبسازی باشد.
بهطور پیشفرض، هر کلید مرتبسازی که در -F مشخص نشده باشد بهطور خودکار پیوست خواهد شد.
اگر کلیدها با پیشوند '+' شروع شوند، فیلد(های) مشخصشده را به ترتیب پیشفرض فیلدها اضافه میکند. برای مثال: perf report -F +period,sample.
-p, --parent=<regex>
-x, --exclude-other
-w, --column-widths=<width[,width...]>
-t, --field-separator=
-D, --dump-raw-trace
-g, --call-graph=<print_type,threshold[,print_limit],order,sort_key[,branch],value>
print_type میتواند یکی از موارد زیر باشد:
- flat: تکستونی، نمایش خطی زنجیرههای فراخوانی.
- graph: استفاده از یک نمودار درختی، نمایش نرخهای سربار مطلق. (پیشفرض)
- fractal: مانند graph، اما نرخهای نسبی را نمایش میدهد. هر شاخه از
درخت به عنوان یک شیء پروفایلشده جدید در نظر گرفته میشود.
- folded: زنجیرههای فراخوانی در یک خط و جداشده با نقطهویرگول نمایش داده میشوند
- none: غیرفعالسازی نمایش زنجیره فراخوانی.
threshold مقداری درصدی است که حداقل درصد لازم را برای گنجانده شدن در گراف فراخوانی خروجی مشخص میکند. پیشفرض 0.5 (%) است.
print_limit تنها زمانی اعمال میشود که از واسط stdio استفاده شود. این برای محدود کردن تعداد مدخلهای گراف فراخوانی در یک مدخل تکی hist است. توجه داشته باشید که باید بعد از threshold مشخص شود (اما لزوماً نباید متوالی باشد). پیشفرض 0 (نامحدود) است.
order میتواند یکی از این موارد باشد: - callee: گراف فراخوانی بر پایه callee. - caller: گراف فراخوانی معکوس بر پایه caller. پیشفرض هنگام استفاده از --children مقدار 'caller' است، در غیر این صورت 'callee'.
sort_key میتواند این موارد باشد: - function: مقایسه بر اساس توابع (پیشفرض) - address: مقایسه بر اساس آدرسهای کد به صورت انفرادی - srcline: مقایسه بر اساس نام فایل مبدأ و شماره خط
branch میتواند این مورد باشد:
- branch: در صورت موجود بودن، اطلاعات آخرین branch در گراف فراخوانی گنجانده شود.
معمولاً استفاده از --branch-history برای این کار راحتتر است.
value میتواند این موارد باشد: - percent: نمایش درصد سربار (پیشفرض) - period: نمایش دوره رویداد - count: نمایش تعداد رویداد
--children
--max-stack
پیشفرض: 127
-G, --inverted
--ignore-callees=<regex>
--pretty=<key>
--stdio
--stdio-color
--tui
--gtk
-k, --vmlinux=<file>
--ignore-vmlinux
--kallsyms=<file>
-m, --modules
-f, --force
--symfs=<directory[,layout]>
-C, --cpu
--source
--asm-raw
--show-total-period
-I, --show-info
-b, --branch-stack
--branch-history
همچنین با برخی پرچمهای شاخه نمایش داده میشود که میتوانند شامل این موارد باشند:
- Predicted: نمایش میانگین درصد شاخههای پیشبینیشده.
(تعداد پیشبینیشده / تعداد کل)
- Abort: نمایش تعداد شاخههای لغوشده tsx.
- Cycles: چرخهها در بلوک پایه (basic block).
--addr2line=<path>
--objdump=<path>
--prefix=PREFIX, --prefix-strip=N
--group
--group-sort-idx
--demangle
--demangle-kernel
--mem-mode
--percent-limit
--percentage
مقدار "relative" بدین معناست که تنها نسبت به مدخلهای پالایششده سنجیده میشود، بهطوری که مجموع مدخلهای نمایشدادهشده همواره 100% خواهد بود. مقدار "absolute" بدین معناست که مقدار اصلی قبل و بعد از اعمال پالایه حفظ میشود.
--header
--header-only
--time
همچنین از درصد زمان با چندین بازه زمانی پشتیبانی میکند. رشته زمان بهصورت 'a%/n,b%/m,...' یا 'a%-b%,c%-%d,...' است.
برای نمونه: انتخاب برش زمانی دوم 10%:
perf report --time 10%/2
انتخاب برش زمانی از 0% تا 10%:
perf report --time 0%-10%
انتخاب برشهای زمانی اول و دوم 10%:
perf report --time 10%/1,10%/2
انتخاب برشهای 0% تا 10% و 30% تا 40%:
perf report --time 0%-10%,30%-40%
این قابلیت میتواند برای اندازهگیری بار کاری فقط پس از اتمام یک فاز مقداردهی اولیه مفید باشد؛ به این صورت که یک perf probe در آن نقطه درج شده و سپس از این گزینه همراه با آن پروب استفاده شود.
--switch-off EVENT_NAME
--show-on-off-events
--itrace
i تولید رویدادهای دستورالعملها (instructions)
y تولید رویدادهای چرخهها (cycles)
b تولید رویدادهای شاخهها (branches)
c تولید رویدادهای شاخهها (فقط فراخوانیها یا calls)
r تولید رویدادهای شاخهها (فقط بازگشتها یا returns)
x تولید رویدادهای تراکنشها (transactions)
w تولید رویدادهای ptwrite
p تولید رویدادهای توان (شامل رویدادهای PSB برای Intel PT)
o تولید سایر رویدادهای ثبتشده به دلیل استفاده
از aux-output (به perf record مراجعه کنید)
I تولید رویدادهای وقفه یا موارد مشابه (ناهمگام)
(مانند Intel PT Event Trace)
e تولید رویدادهای خطا (error)
d ایجاد یک گزارش اشکالزدایی (debug log)
f تولید رویدادهای حافظه پنهان سطح اول (L1 cache)
m تولید رویدادهای حافظه پنهان سطح آخر (LLC)
M تولید رویدادهای حافظه (memory)
t تولید رویدادهای TLB
a تولید رویدادهای دسترسی از راه دور (remote access)
g تولید یک زنجیره فراخوانی (همراه با i یا x استفاده شود)
G تولید زنجیره فراخوانی روی رکوردهای رویداد موجود
l تولید ورودیهای آخرین شاخه (همراه با i یا x استفاده شود)
L تولید ورودیهای آخرین شاخه روی رکوردهای رویداد موجود
s صرفنظر کردن از تعداد اولیهای از رویدادها
q رمزگشایی سریعتر (با جزئیات کمتر)
A تخمین تقریبی IPC
Z ترجیح به نادیده گرفتن برچسبهای زمانی (رمزگشایی اصطلاحاً «timeless»)
T استفاده از برچسب زمانی ردگیری بهعنوان زمان هسته (kernel time)
حالت پیشفرض شامل تمام رویدادها است؛ یعنی مشابه --itrace=iybxwpe، بهجز در perf script که پیشفرض آن --itrace=ce میباشد.
علاوه بر این، دوره یا Period (پیشفرض ۱۰۰۰۰۰، بهجز در perf script که ۱ است) برای رویدادهای دستورالعملها را میتوان بر حسب این واحدها تعیین کرد:
i دستورالعملها (instructions) t تیکها (ticks) ms میلیثانیه us میکروثانیه ns نانوثانیه (پیشفرض)
همچنین اندازه زنجیره فراخوانی (پیشفرض ۱۶، حداکثر ۱۰۲۴) برای رویدادهای دستورالعملها یا تراکنشها قابل تعیین است.
همچنین تعداد ورودیهای آخرین شاخه (پیشفرض ۶۴، حداکثر ۱۰۲۴) برای رویدادهای دستورالعملها یا تراکنشها قابل تعیین است.
مشابه گزینههای g و l، اندازه را میتوان برای گزینههای G و L نیز تعیین کرد. در x86 توجه داشته باشید که اگر دادهها با PEBS بزرگ ثبت شده باشند، عملکرد G و L بسیار ضعیف خواهد بود. برای جزئیات به صفحه راهنمای linkperf:perf-intel-pt[1] مراجعه کنید.
همچنین امکان رد کردن رویدادهای اولیهی تولیدشده (دستورالعملها، شاخهها، تراکنشها، ptwrite، توان) وجود دارد. این قابلیت برای نادیده گرفتن کدهای مقداردهی اولیه سودمند است.
--itrace=i0nss1000000
از یک میلیون دستورالعمل نخست صرفنظر میکند.
گزینه 'e' میتواند با پرچمهایی دنبال شود که مشخص میکنند چه خطاهایی گزارش
بشوند یا نشوند. هر پرچم باید قبل از خود یک '+' یا '-' داشته باشد.
این پرچمها عبارتند از:
o سرریز (overflow)
l از دست رفتن دادههای ردگیری (trace data lost)
در صورت پشتیبانی، گزینه 'd' میتواند با پرچمهایی دنبال شود که بر پیامهای
اشکالزداییِ ثبتی اثر میگذارند. هر پرچم باید قبل از خود یک '+' یا '-'
داشته باشد. این پرچمها عبارتند از:
a تمام رویدادهای perf
e خروجی تنها هنگام بروز خطا (اندازه قابل تنظیم است - به linkperf:perf-config[1] مراجعه کنید)
o خروجی به stdout
در صورت پشتیبانی، میتوان گزینه 'q' را برای افزایش اثر آن تکرار کرد.
برای غیرفعالسازی کامل فرایند رمزگشایی، از --no-itrace استفاده کنید.
--show-ref-call-graph
--stitch-lbr
--socket-filter
--samples=N
--raw-trace
-H, --hierarchy
برای مثال: در خروجی عادی:
perf report -s dso,sym
# Overhead Shared Object Symbol
50.00% [kernel.kallsyms] [k] kfunc1
20.00% perf [.] foo
15.00% [kernel.kallsyms] [k] kfunc2
10.00% perf [.] bar
5.00% libc.so [.] libcall
در خروجی سلسلهمراتبی:
perf report -s dso,sym --hierarchy
# Overhead Shared Object / Symbol
65.00% [kernel.kallsyms]
50.00% [k] kfunc1
15.00% [k] kfunc2
30.00% perf
20.00% [.] foo
10.00% [.] bar
5.00% libc.so
5.00% [.] libcall
--inline
--mmaps
لطفاً توجه داشته باشید که تمام mmapها ذخیره نمیشوند؛ گزینههای تأثیرگذار بر موارد شاملشده، برای نمونه عبارتند از 'perf record --data'.
--ns
--stats
--tasks
--percent-type
کلیدواژههای local/global تعیین میکنند که آیا درصد در دامنه تابع (local) محاسبه شود یا در کل دادهها (global). کلیدواژههای period/hits مبنای محاسبه درصد را مشخص میکنند - دوره نمونهها (period) یا تعداد نمونهها (hits).
--time-quantum
--total-cycles
'Sampled Cycles%' - تجمیع چرخههای نمونهبرداریشده بلوک / کل چرخههای نمونهبرداریشده
'Sampled Cycles' - تجمیع چرخههای نمونهبرداریشده بلوک
'Avg Cycles%' - میانگین چرخههای نمونهبرداریشده بلوک / مجموع میانگین کل
چرخههای نمونهبرداریشده بلوک
'Avg Cycles' - میانگین چرخههای نمونهبرداریشده بلوک
'Branch Counter' - هیستوگرام شمارنده انشعاب بلوک (با -v تعداد نمایش داده میشود)
--skip-empty
دو مفهوم از زمان وجود دارد: زمان ساعت دیواری (wall-clock time) و زمان پردازنده (CPU time). برای یک برنامه تکنخی، یا برنامهای که روی یک ماشین تکهستهای اجرا میشود، این مفاهیم یکسان هستند. با این حال، برای یک برنامه چندنخی/چندفرآیندی که روی یک ماشین چندهستهای اجرا میشود، این مفاهیم تفاوت چشمگیری دارند. در ازای هر ثانیه از زمان ساعت دیواری، به تعداد هستهها ثانیه زمان پردازنده داریم. ابزار perf میتواند سربار را برای هر دو زمان اندازه بگیرد (که به ترتیب در ستونهای overhead و latency برای زمان پردازنده و زمان ساعت دیواری نشان داده میشوند).
بهینهسازی سربار پردازنده برای بهبود توان عملیاتی (throughput) مفید است، در حالی که بهینهسازی سربار تاخیر برای بهبود تاخیر (latency) سودمند است. درک این که کدامیک در یک موقعیت عملی پیشرو مفید است اهمیت بالایی دارد. برای نمونه، مورد نخست ممکن است برای بهبود حداکثر توان عملیاتی یک سرور ساخت CI که با بهرهگیری ۱۰۰٪ از پردازنده کار میکند مفید باشد، در حالی که مورد دوم ممکن است برای بهبود تاخیر درکشده توسط کاربر در ساخت یک برنامه تعاملی کارآمد باشد. این سربارها ممکن است در برخی موارد تفاوت فاحشی داشته باشند. برای مثال، برنامهای را در نظر بگیرید که تابع foo را به مدت ۹ ثانیه با ۱ نخ اجرا میکند، و سپس تابع bar را به مدت ۱ ثانیه با ۱۲۸ نخ به اجرا درمیآورد (۱۲۸ ثانیه زمان پردازنده مصرف میکند). سربار پردازنده عبارت است از: foo - 6.6%، bar - 93.4%. در حالی که سربار تاخیر عبارت است از: foo - 90%، bar - 10%. اگر تلاش کنیم با در نظر گرفتن سربار پردازنده (که در این مورد گمراهکننده است) زمان اجرای برنامه را بهینهسازی کنیم، روی تابع bar تمرکز خواهیم کرد، اما این کار در بهترین حالت تنها میتواند ۱۰٪ زمان اجرا را بهبود بخشد.
بهطور پیشفرض، perf تنها سربار پردازنده را نشان میدهد. برای نمایش سربار تاخیر، از perf record --latency و perf report استفاده کنید:
.ft C Overhead Latency Command 93.88% 25.79% cc1 1.90% 39.87% gzip 0.99% 10.16% dpkg-deb 0.57% 1.00% as 0.40% 0.46% sh .ft
برای مرتبسازی بر اساس سربار تاخیر، از perf report --latency استفاده کنید:
.ft C Latency Overhead Command 39.87% 1.90% gzip 25.79% 93.88% cc1 10.16% 0.99% dpkg-deb 4.17% 0.29% git 2.81% 0.11% objtool .ft
برای دستیابی به درک دقیقتری از تفاوت میان سربارها، میتوانید هیستوگرام موازیسازی را با پرچمهای --sort=latency,parallelism,comm,symbol --hierarchy بررسی کنید. این کار کسری از زمان (ساعت دیواری) را که در آن بار کاری از تعداد متفاوتی هسته استفاده میکند، نشان میدهد (ستون Parallelism). برای نمونه، در مورد زیر بار کاری در بیشتر زمان تنها از ۱ هسته استفاده میکند، اما دارای فازهایی با موازیسازی بسیار بالا نیز هست که تفاوت چشمگیر میان سربارهای پردازنده و ساعت دیواری را توجیه میکند:
.ft C Latency Overhead Parallelism / Command / Symbol + 56.98% 2.29% 1 + 16.94% 1.36% 2 + 4.00% 20.13% 125 + 3.66% 18.25% 124 + 3.48% 17.66% 126 + 3.26% 0.39% 3 + 2.61% 12.93% 123 .ft
با باز کردن خطوط مربوطه، میتوانید ببینید چه دستورها/توابعی در سطح موازیسازی مشخص اجرا میشوند:
.ft C
Latency Overhead Parallelism / Command / Symbol
- 56.98% 2.29% 1
32.80% 1.32% gzip
4.46% 0.18% cc1
2.81% 0.11% objtool
2.43% 0.10% dpkg-source
2.22% 0.09% ld
2.10% 0.08% dpkg-genchanges
.ft
برای مشاهده نمایه معمولی در سطح توابع برای سطوح موازیسازی مشخص (تعداد نخهایی که بهطور فعال روی پردازندهها در حال اجرا هستند)، میتوانید از فیلتر --parallelism استفاده کنید. برای مثال، جهت مشاهده نمایه فقط برای فازهای با موازیسازی پایین یک بار کاری، از پرچمهای --latency --parallelism=1-2 استفاده کنید.
محاسبه سربار (OVERHEAD CALCULATION)
هنگامی که perf زنجیرههای فراخوانی (callchains) را گردآوری میکند، سربار پردازنده میتواند در دو ستون Children و Self نمایش داده شود (و ستونهای متناظر Wall برای سربار زمان ساعت دیواری). سربار self صرفاً با جمع زدن تمامی مقادیر دورهها (period) مربوط به یک مدخل - معمولاً یک تابع (نماد) - محاسبه میشود. این مقداری است که perf بهطور سنتی نمایش میدهد و مجموع تمام مقادیر سربار self باید ۱۰۰٪ باشد.
سربار children با افزودن تمامی مقادیر دورههای توابع فرزند محاسبه میشود تا بتواند کل سربار توابع سطح بالاتر را نشان دهد، حتی اگر آنها مستقیماً کار زیادی انجام ندهند. در اینجا منظور از Children توابعی است که از تابعی دیگر (والد) فراخوانی شدهاند.
شاید گیجکننده به نظر برسد که مجموع تمام مقادیر سربار children از ۱۰۰٪ بیشتر میشود، زیرا هر یک از آنها خود تجمعی از سربار self توابع فرزندش است. اما با فعال بودن این مورد، کاربران میتوانند تشخیص دهند کدام تابع بیشترین سربار را دارد حتی اگر نمونهها میان توابع فرزند پراکنده باشند.
مثال زیر را در نظر بگیرید؛ سه تابع مانند زیر وجود دارند.
.ft C
void foo(void) {
/* do something */
}
void bar(void) {
/* do something */
foo();
}
int main(void) {
bar()
return 0;
}
.ft
در این حالت foo فرزندی برای bar است، و bar فرزند بیواسطه main است، بنابراین foo نیز فرزند main به شمار میرود. به بیان دیگر، main والد foo و bar است، و bar والد foo است.
فرض کنید تمام نمونهها فقط در foo و bar ثبت شدهاند. هنگامی که نمونهبرداری با زنجیرههای فراخوانی انجام شود، خروجی در حالت معمول (فقط سربار self) دستور perf report چیزی مانند زیر را نشان خواهد داد:
.ft C
Overhead Symbol
........ .....................
60.00% foo
|
--- foo
bar
main
__libc_start_main
40.00% bar
|
--- bar
main
__libc_start_main
.ft
هنگامی که گزینه --children فعال باشد، مقادیر سربار self توابع فرزند (یعنی foo و bar) به والدین افزوده میشوند تا سربار children محاسبه شود. در این حالت گزارش ممکن است به این صورت نمایش داده شود:
.ft C
Children Self Symbol
........ ........ ....................
100.00% 0.00% __libc_start_main
|
--- __libc_start_main
100.00% 0.00% main
|
--- main
__libc_start_main
100.00% 40.00% bar
|
--- bar
main
__libc_start_main
60.00% 60.00% foo
|
--- foo
bar
main
__libc_start_main
.ft
در خروجی بالا، سربار self تابع foo (۶۰٪) به سربار children مربوط به bar، main و __libc_start_main افزوده شد. به همین ترتیب، سربار self تابع bar (۴۰٪) به سربار children مربوط به main و \_\_libc_start_main اضافه شد.
بنابراین \_\_libc_start_main و main در ابتدا نمایش داده میشوند، زیرا سربار children یکسانی (۱۰۰٪) دارند (اگرچه سربار self آنها صفر است) و آنها والدین foo و bar هستند.
از نسخه v3.16 به بعد، سربار children بهطور پیشفرض نمایش داده میشود و خروجی بر اساس مقادیر آن مرتب میگردد. سربار children را میتوان با مشخص کردن گزینه --no-children در خط فرمان یا افزودن report.children = false یا top.children = false در فایل پیکربندی perf غیرفعال کرد..SH "همچنین ببینید (SEE ALSO)"
perf-stat(1), perf-annotate(1), perf-record(1), perf-intel-pt(1)
| 09/04/2026 | perf |