সি ++ প্রোফাইলিংয়ের কৌশলগুলির সমীক্ষা
এই উত্তরে, আমি কয়েকটি খুব সাধারণ পরীক্ষা প্রোগ্রাম বিশ্লেষণ করতে বিভিন্ন সরঞ্জাম ব্যবহার করব, যাতে সেই সরঞ্জামগুলি কীভাবে কাজ করে তা তুলনামূলকভাবে তুলনা করতে পারি।
নিম্নলিখিত পরীক্ষার প্রোগ্রামটি খুব সাধারণ এবং নিম্নলিখিতটি করে:
main
কল fast
এবং maybe_slow
3 বার, maybe_slow
কলগুলির মধ্যে একটি ধীর হচ্ছে
ধীর কলটি maybe_slow
10x দীর্ঘ, এবং আমরা যদি শিশু ফাংশনটিতে কল বিবেচনা করি তবে রানটাইমকে প্রাধান্য দেয় common
। আদর্শভাবে, প্রোফাইলিং সরঞ্জামটি নির্দিষ্ট ধীর কলকে আমাদের নির্দেশ করতে সক্ষম হবে।
উভয় fast
এবং maybe_slow
কল common
, যা প্রোগ্রামের প্রচুর পরিমাণে কার্যকর করে
প্রোগ্রাম ইন্টারফেসটি হ'ল:
./main.out [n [seed]]
এবং প্রোগ্রাম O(n^2)
মোট লুপ করে না। seed
রানটাইমকে প্রভাবিত না করেই কেবল ভিন্ন আউটপুট পেতে হয়।
main.c
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
uint64_t __attribute__ ((noinline)) common(uint64_t n, uint64_t seed) {
for (uint64_t i = 0; i < n; ++i) {
seed = (seed * seed) - (3 * seed) + 1;
}
return seed;
}
uint64_t __attribute__ ((noinline)) fast(uint64_t n, uint64_t seed) {
uint64_t max = (n / 10) + 1;
for (uint64_t i = 0; i < max; ++i) {
seed = common(n, (seed * seed) - (3 * seed) + 1);
}
return seed;
}
uint64_t __attribute__ ((noinline)) maybe_slow(uint64_t n, uint64_t seed, int is_slow) {
uint64_t max = n;
if (is_slow) {
max *= 10;
}
for (uint64_t i = 0; i < max; ++i) {
seed = common(n, (seed * seed) - (3 * seed) + 1);
}
return seed;
}
int main(int argc, char **argv) {
uint64_t n, seed;
if (argc > 1) {
n = strtoll(argv[1], NULL, 0);
} else {
n = 1;
}
if (argc > 2) {
seed = strtoll(argv[2], NULL, 0);
} else {
seed = 0;
}
seed += maybe_slow(n, seed, 0);
seed += fast(n, seed);
seed += maybe_slow(n, seed, 1);
seed += fast(n, seed);
seed += maybe_slow(n, seed, 0);
seed += fast(n, seed);
printf("%" PRIX64 "\n", seed);
return EXIT_SUCCESS;
}
gprof
জিআরফোফের জন্য ইন্সট্রুমেন্টেশন সহ সফটওয়্যারটি পুনরায় সংশ্লেষ করা প্রয়োজন এবং এটি সেই যন্ত্রটির সাথে একটি নমুনা পদ্ধতিরও ব্যবহার করে। সুতরাং এটি নির্ভুলতার মধ্যে ভারসাম্য রোধ করে (নমুনা সর্বদা পুরোপুরি নির্ভুল হয় না এবং ফাংশনগুলি এড়িয়ে যেতে পারে) এবং সম্পাদন মন্দা (যন্ত্র এবং নমুনা তুলনামূলকভাবে দ্রুত কৌশল যা কার্যকরভাবে খুব বেশি গতি দেয় না)।
জিআরফোফটি জিসিসি / বাইনুটিসগুলি অন্তর্নির্মিত, তাই আমাদের যা করতে হবে তা -pg
হ'ল gprof সক্ষম করার বিকল্পটি সংকলন করা । তারপরে আমরা একটি আকারের সিএলআই প্যারামিটার দিয়ে প্রোগ্রামটি সাধারণত চালিত করি যা কয়েক সেকেন্ডের যুক্তিসঙ্গত সময়কাল ধরে রান তৈরি করে ( 10000
):
gcc -pg -ggdb3 -O3 -std=c99 -Wall -Wextra -pedantic -o main.out main.c
time ./main.out 10000
শিক্ষাগত কারণে, আমরা অপ্টিমাইজেশন সক্ষম না করেও একটি রান করব। মনে রাখবেন যে এটি ব্যবহারে অকেজো, কারণ আপনি সাধারণত কেবলমাত্র অনুকূলিত প্রোগ্রামটির পারফরম্যান্সকেই অনুকূল করেন:
gcc -pg -ggdb3 -O0 -std=c99 -Wall -Wextra -pedantic -o main.out main.c
./main.out 10000
প্রথমে time
আমাদের জানান যে মৃত্যুদণ্ড কার্যকর করার সময়টি তার সাথে বা তার বাইরে -pg
একই ছিল, যা দুর্দান্ত: কোনও ধীরগতি নেই! আমি তবে জটিল সফ্টওয়্যারগুলিতে 2x - 3X ধীরগতির অ্যাকাউন্ট দেখেছি, যেমন এই টিকিটে দেখানো হয়েছে ।
যেহেতু আমরা সংকলন করেছি -pg
, প্রোগ্রামটি চালনা করে এমন একটি ফাইল gmon.out
ফাইল তৈরি করে যাতে প্রোফাইলিং ডেটা থাকে।
আমরা সেই ফাইলটি গ্রাফিকভাবে gprof2dot
যেমনটি জিজ্ঞাসা করেছি তা পর্যবেক্ষণ করতে পারি : জিআরএফ ফলাফলের গ্রাফিকাল উপস্থাপনা পাওয়া কি সম্ভব?
sudo apt install graphviz
python3 -m pip install --user gprof2dot
gprof main.out > main.gprof
gprof2dot < main.gprof | dot -Tsvg -o output.svg
এখানে, gprof
সরঞ্জামটি gmon.out
ট্রেস তথ্যটি পড়ে এবং একটি মানব পাঠযোগ্য প্রতিবেদন তৈরি করে main.gprof
, যা gprof2dot
পরে গ্রাফ তৈরি করতে পড়ে।
Gprof2dot এর উত্সটি এখানে: https://github.com/jrfonseca/gprof2dot
আমরা -O0
রান জন্য নিম্নলিখিত পর্যবেক্ষণ :
এবং -O3
রান জন্য:
-O0
আউটপুট প্রায় কাছাকাছি স্বশাসিত হয়। উদাহরণস্বরূপ, এটি দেখায় যে 3 টি maybe_slow
কল এবং তাদের শিশু কলগুলি মোট রানটাইমের 97৯..5 take% সময় নেয়, যদিও maybe_slow
শিশু ছাড়া নিজেকে নির্বাহ করা মোট মৃত্যুদন্ডের সময়টির ০.০০%, অর্থাৎ এই কার্যক্রমে ব্যয় করা প্রায় সমস্ত সময়ই ব্যয় করেছিল although শিশু কল।
টোডো: আমি জিডিবিতে দেখতে পাচ্ছি, তবে কেন আউটপুটটি main
অনুপস্থিত ? জিপিআরএফ আউটপুট থেকে অনুপস্থিত ফাংশনটি আমি মনে করি কারণ এটি জিপিআরএফ এর সংকলিত উপকরণ ছাড়াও নমুনা তৈরি করছে, এবং এটি খুব দ্রুত এবং কোনও নমুনাও পায় নি।-O3
bt
-O3
main
আমি পিএনজির পরিবর্তে এসভিজি আউটপুট চয়ন করি কারণ এসভিজি সিটিআরএল + এফ দ্বারা অনুসন্ধানযোগ্য এবং ফাইলের আকার প্রায় 10x ছোট হতে পারে। এছাড়াও, তৈরি সফটওয়্যারটির প্রস্থ এবং উচ্চতা জটিল সফ্টওয়্যারটির জন্য কয়েক হাজার পিক্সেল এবং eog
পিএনজিগুলির জন্য জিনোম ৩.২৮.১ বাগগুলি খুঁজে পাওয়া যায়, যখন এসভিজিগুলি আমার ব্রাউজারটি স্বয়ংক্রিয়ভাবে খুলে যায়। গিম্প ২.৮ যদিও ভাল কাজ করেছে, তাও দেখুন:
তবে তারপরেও, আপনি যা চান তা সন্ধান করার জন্য আপনি চিত্রটি প্রচুর আশেপাশে টেনে আনবেন, উদাহরণস্বরূপ এই টিকেট থেকে নেওয়া "বাস্তব" সফ্টওয়্যার উদাহরণ থেকে এই চিত্রটি দেখুন :
আপনি কি খুব সহজেই এই সমস্ত ক্ষুদ্র অরসোর্টড স্প্যাগেটি লাইনের একে অপরের সাথে চলে যাওয়ার সাথে খুব সহজেই কল স্ট্যাক খুঁজে পেতে পারেন? dot
আমি নিশ্চিত আরও ভাল বিকল্প থাকতে পারে , কিন্তু আমি এখন সেখানে যেতে চাই না। আমাদের যা প্রয়োজন তা হ'ল এটির জন্য উপযুক্ত উত্সর্গীকৃত দর্শক, তবে আমি এখনও এটি পাইনি:
তবে আপনি এই সমস্যাগুলি কিছুটা কমিয়ে আনতে রঙিন মানচিত্রটি ব্যবহার করতে পারেন। উদাহরণস্বরূপ, পূর্ববর্তী বিশাল চিত্রটিতে, আমি শেষ পর্যন্ত বাম দিকে সমালোচনামূলক পথটি সন্ধান করতে সক্ষম হয়েছি যখন আমি উজ্জ্বল ছাড়টি তৈরি করি যা সবুজ লাল পরে আসে, তার পরে অবশেষে গা and় এবং গাer় নীল।
বিকল্পভাবে, আমরা gprof
অন্তর্নির্মিত বিন্টুলি সরঞ্জামের পাঠ্য আউটপুটটি পর্যবেক্ষণ করতে পারি যা আমরা পূর্বে এখানে সংরক্ষণ করেছি:
cat main.gprof
ডিফল্টরূপে, এটি একটি অত্যন্ত ভার্বোস আউটপুট তৈরি করে যা আউটপুট ডেটার অর্থ কী তা ব্যাখ্যা করে। যেহেতু আমি এর চেয়ে ভাল ব্যাখ্যা করতে পারি না, তাই আমি আপনাকে এটি নিজে পড়তে দেব।
একবার আপনি ডেটা আউটপুট ফর্ম্যাটটি বুঝতে পারলে, -b
বিকল্পটির সাহায্যে টিউটোরিয়াল ছাড়াই কেবল ডেটা দেখানোর জন্য আপনি ভার্বোসিটি হ্রাস করতে পারেন :
gprof -b main.out
আমাদের উদাহরণস্বরূপ, আউটপুটগুলি ছিল -O0
:
Flat profile:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls s/call s/call name
100.35 3.67 3.67 123003 0.00 0.00 common
0.00 3.67 0.00 3 0.00 0.03 fast
0.00 3.67 0.00 3 0.00 1.19 maybe_slow
Call graph
granularity: each sample hit covers 2 byte(s) for 0.27% of 3.67 seconds
index % time self children called name
0.09 0.00 3003/123003 fast [4]
3.58 0.00 120000/123003 maybe_slow [3]
[1] 100.0 3.67 0.00 123003 common [1]
-----------------------------------------------
<spontaneous>
[2] 100.0 0.00 3.67 main [2]
0.00 3.58 3/3 maybe_slow [3]
0.00 0.09 3/3 fast [4]
-----------------------------------------------
0.00 3.58 3/3 main [2]
[3] 97.6 0.00 3.58 3 maybe_slow [3]
3.58 0.00 120000/123003 common [1]
-----------------------------------------------
0.00 0.09 3/3 main [2]
[4] 2.4 0.00 0.09 3 fast [4]
0.09 0.00 3003/123003 common [1]
-----------------------------------------------
Index by function name
[1] common [4] fast [3] maybe_slow
এবং এর জন্য -O3
:
Flat profile:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls us/call us/call name
100.52 1.84 1.84 123003 14.96 14.96 common
Call graph
granularity: each sample hit covers 2 byte(s) for 0.54% of 1.84 seconds
index % time self children called name
0.04 0.00 3003/123003 fast [3]
1.79 0.00 120000/123003 maybe_slow [2]
[1] 100.0 1.84 0.00 123003 common [1]
-----------------------------------------------
<spontaneous>
[2] 97.6 0.00 1.79 maybe_slow [2]
1.79 0.00 120000/123003 common [1]
-----------------------------------------------
<spontaneous>
[3] 2.4 0.00 0.04 fast [3]
0.04 0.00 3003/123003 common [1]
-----------------------------------------------
Index by function name
[1] common
প্রতিটি বিভাগের খুব দ্রুত সংক্ষিপ্তসার হিসাবে যেমন:
0.00 3.58 3/3 main [2]
[3] 97.6 0.00 3.58 3 maybe_slow [3]
3.58 0.00 120000/123003 common [1]
ফাংশনটির চারপাশে কেন্দ্রগুলি থাকে যা ইন্ডেন্ট করা থাকে ( maybe_flow
)। [3]
এই ফাংশনটির আইডি। ফাংশনের উপরে, তার কলারগুলি রয়েছে এবং এর নীচে কলি রয়েছে।
জন্য -O3
, যে গ্রাফিক্যাল আউটপুটে মত এখানে দেখতে maybe_slow
এবং fast
একটি পরিচিত পিতা বা মাতা, যা কি ডকুমেন্টেশন বলছেন যে হবে না <spontaneous>
উপায়।
আমি নিশ্চিত নই যে জিপিআরফের সাথে লাইন বাই লাইন প্রোফাইলিং করার কোনও দুর্দান্ত উপায় আছে কিনা: code জিপিআরএফ সময় নির্দিষ্ট কোডের লাইনে ব্যয় করে
Valgrind কলগ্রাইন্ড
valgrind Valgrind ভার্চুয়াল মেশিনের মাধ্যমে প্রোগ্রামটি চালায়। এটি প্রোফাইলিংটি খুব নির্ভুল করে তোলে তবে এটি প্রোগ্রামের একটি খুব বড় ধীর গতিও তৈরি করে। আমি আগে kcachegrind উল্লেখ করেছি: কোডের একটি চিত্রযুক্ত ফাংশন কল গ্রাফ পেতে সরঞ্জাম
কলগ্রাইন্ডটি প্রোফাইল কোডের জন্য ভালগ্রাইন্ডের হাতিয়ার এবং কেচাগ্রাইন্ড একটি কে-ডি প্রোগ্রাম যা ক্যাশেগ্রিন্ড আউটপুটটিকে কল্পনা করতে পারে।
প্রথমে আমাদের -pg
স্বাভাবিক সংকলনে ফিরে যাওয়ার জন্য পতাকাটি সরাতে হবে , অন্যথায় রানটি আসলে ব্যর্থ হয় Profiling timer expired
এবং হ্যাঁ, এটি এতটাই সাধারণ যে আমি এটি করেছি এবং এর জন্য একটি স্ট্যাক ওভারফ্লো প্রশ্ন ছিল।
সুতরাং আমরা সংকলন এবং হিসাবে চালানো:
sudo apt install kcachegrind valgrind
gcc -ggdb3 -O3 -std=c99 -Wall -Wextra -pedantic -o main.out main.c
time valgrind --tool=callgrind valgrind --dump-instr=yes \
--collect-jumps=yes ./main.out 10000
আমি সক্ষম করি --dump-instr=yes --collect-jumps=yes
কারণ এটি এমন তথ্যও ফেলে দেয় যা তুলনামূলকভাবে ছোট সংযোজন ওভারহেড ব্যয় করে আমাদের প্রতি পারফরম্যান্সের লাইন বিভাজন দেখতে সক্ষম করে।
ব্যাট বন্ধ, time
আমাদের বলে যে প্রোগ্রামটি কার্যকর করতে 29.5 সেকেন্ড সময় নিয়েছে, সুতরাং আমাদের এই উদাহরণটিতে প্রায় 15x এর মন্দা ছিল। স্পষ্টতই, এই মন্দা বড় কাজের চাপের জন্য একটি গুরুতর সীমাবদ্ধতা হতে চলেছে। এখানে উল্লিখিত "রিয়েল ওয়ার্ল্ড সফ্টওয়্যার উদাহরণ" এ , আমি ৮০x এর মন্দা লক্ষ্য করেছি।
রানটি আমার ক্ষেত্রে callgrind.out.<pid>
যেমন একটি প্রোফাইল ডেটা ফাইল তৈরি করে callgrind.out.8554
। আমরা ফাইলটি এর সাথে দেখি:
kcachegrind callgrind.out.8554
যা এমন একটি জিইউআই দেখায় যা পাঠ্য জিআরএফআউটপটের অনুরূপ ডেটা ধারণ করে:
এছাড়াও, যদি আমরা নীচে ডান "কল গ্রাফ" ট্যাবটিতে যাই, আমরা কল কলম দেখতে পাই যা আমরা অযৌক্তিক পরিমাণে সাদা সীমানা সহ নিম্নলিখিত চিত্রটি পেতে নীচে ক্লিক করে রফতানি করতে পারি :-)
আমি মনে করি fast
সেই গ্রাফটিতে প্রদর্শিত হচ্ছে না কারণ কেচাগ্রাইন্ড অবশ্যই ভিজ্যুয়ালাইজেশনকে সহজ করেছে কারণ সেই কলটি খুব কম সময় নেয়, সম্ভবত এটিই আপনি আসল প্রোগ্রামে চান এমন আচরণ হতে পারে। ডান ক্লিক মেনুতে এমন নোডগুলি কখন বন্ধ করতে হবে তা নিয়ন্ত্রণ করার জন্য কিছু সেটিংস রয়েছে তবে দ্রুত চেষ্টা করার পরেও আমি এটি একটি ছোট কলটি দেখতে পেলাম না। আমি যদি fast
বাম উইন্ডোতে ক্লিক করি তবে এটি কল কল দেখায় fast
, যাতে স্ট্যাকটি আসলে ধরা পড়ে। সম্পূর্ণ গ্রাফ কল গ্রাফ দেখানোর জন্য এখনও কোনও উপায় খুঁজে পায়নি : কলগ্রাইন্ড কে কেচেগ্রিন্ড কলগ্রাফের সমস্ত ফাংশন কল দেখান
জটিল সি ++ সফটওয়্যারটিতে টুডো, আমি টাইপের কিছু এন্ট্রি দেখতে পাচ্ছি <cycle N>
, উদাহরণস্বরূপ <cycle 11>
যেখানে আমি ফাংশনটির নাম আশা করব, তার অর্থ কী? আমি লক্ষ্য করেছি যে এটি চালু এবং বন্ধ টগল করার জন্য একটি "সাইকেল সনাক্তকরণ" বোতাম রয়েছে, তবে এর অর্থ কী?
perf
থেকে linux-tools
perf
একচেটিয়াভাবে লিনাক্স কার্নেল স্যাম্পলিং প্রক্রিয়াগুলি ব্যবহার করছে বলে মনে হয়। এটি সেটআপ করা খুব সহজ করে তোলে, তবে পুরোপুরি সঠিকও নয়।
sudo apt install linux-tools
time perf record -g ./main.out 10000
এটি মৃত্যুদন্ডের সাথে 0.2 টি যোগ করেছে, তাই আমরা সময়মতো ভাল, তবে common
কিবোর্ডের ডান তীর দিয়ে নোডটি প্রসারিত করার পরেও আমি তেমন আগ্রহ দেখি না :
Samples: 7K of event 'cycles:uppp', Event count (approx.): 6228527608
Children Self Command Shared Object Symbol
- 99.98% 99.88% main.out main.out [.] common
common
0.11% 0.11% main.out [kernel] [k] 0xffffffff8a6009e7
0.01% 0.01% main.out [kernel] [k] 0xffffffff8a600158
0.01% 0.00% main.out [unknown] [k] 0x0000000000000040
0.01% 0.00% main.out ld-2.27.so [.] _dl_sysdep_start
0.01% 0.00% main.out ld-2.27.so [.] dl_main
0.01% 0.00% main.out ld-2.27.so [.] mprotect
0.01% 0.00% main.out ld-2.27.so [.] _dl_map_object
0.01% 0.00% main.out ld-2.27.so [.] _xstat
0.00% 0.00% main.out ld-2.27.so [.] __GI___tunables_init
0.00% 0.00% main.out [unknown] [.] 0x2f3d4f4944555453
0.00% 0.00% main.out [unknown] [.] 0x00007fff3cfc57ac
0.00% 0.00% main.out ld-2.27.so [.] _start
সুতরাং আমি -O0
প্রোগ্রামটিকে বেঞ্চমার্ক করার চেষ্টা করি যাতে এটি কিছু দেখায় কিনা এবং কেবল এখনই, শেষ পর্যন্ত, আমি কি কোনও কল গ্রাফ দেখতে পাচ্ছি:
Samples: 15K of event 'cycles:uppp', Event count (approx.): 12438962281
Children Self Command Shared Object Symbol
+ 99.99% 0.00% main.out [unknown] [.] 0x04be258d4c544155
+ 99.99% 0.00% main.out libc-2.27.so [.] __libc_start_main
- 99.99% 0.00% main.out main.out [.] main
- main
- 97.54% maybe_slow
common
- 2.45% fast
common
+ 99.96% 99.85% main.out main.out [.] common
+ 97.54% 0.03% main.out main.out [.] maybe_slow
+ 2.45% 0.00% main.out main.out [.] fast
0.11% 0.11% main.out [kernel] [k] 0xffffffff8a6009e7
0.00% 0.00% main.out [unknown] [k] 0x0000000000000040
0.00% 0.00% main.out ld-2.27.so [.] _dl_sysdep_start
0.00% 0.00% main.out ld-2.27.so [.] dl_main
0.00% 0.00% main.out ld-2.27.so [.] _dl_lookup_symbol_x
0.00% 0.00% main.out [kernel] [k] 0xffffffff8a600158
0.00% 0.00% main.out ld-2.27.so [.] mmap64
0.00% 0.00% main.out ld-2.27.so [.] _dl_map_object
0.00% 0.00% main.out ld-2.27.so [.] __GI___tunables_init
0.00% 0.00% main.out [unknown] [.] 0x552e53555f6e653d
0.00% 0.00% main.out [unknown] [.] 0x00007ffe1cf20fdb
0.00% 0.00% main.out ld-2.27.so [.] _start
টোডো: -O3
ফাঁসির ঘটনায় কী ঘটেছিল ? এটি কি কেবল সহজ maybe_slow
এবং fast
খুব দ্রুত ছিল এবং কোনও নমুনা পেল না? এটি -O3
কার্যকর হতে আরও বেশি সময় নেয় এমন বড় প্রোগ্রামগুলির সাথে কী ভাল কাজ করে? আমি কি কিছু সি এল এল বিকল্প মিস করেছি? -F
হার্টজে নমুনা ফ্রিকোয়েন্সি নিয়ন্ত্রণ করার বিষয়ে আমি জানতে পেরেছি , কিন্তু আমি এটিকে ডিফল্টরূপে অনুমোদিত সর্বোচ্চ -F 39500
(এটি দিয়ে বাড়ানো যেতে পারে sudo
) পর্যন্ত পরিণত করেছি এবং আমি এখনও পরিষ্কার কল দেখতে পাচ্ছি না।
perf
ব্র্যান্ডন গ্রেগের ফ্ল্যামগ্রাফ সরঞ্জাম সম্পর্কে একটি দুর্দান্ত জিনিস হ'ল কল স্ট্যাকের সময়গুলি খুব ঝরঝরেভাবে প্রদর্শন করে যা আপনাকে দ্রুত বড় কলগুলি দেখতে দেয়। টুল পাওয়া যাবে: https://github.com/brendangregg/FlameGraph এবং এ তার জন্য perf টিউটোরিয়াল উল্লেখ করা হয়: http://www.brendangregg.com/perf.html#FlameGraphs যখন আমি দৌড়ে perf
ছাড়া sudo
আমি পেয়েছিলাম ERROR: No stack counts found
তাই জন্য এখন আমি এটি দিয়ে করব sudo
:
git clone https://github.com/brendangregg/FlameGraph
sudo perf record -F 99 -g -o perf_with_stack.data ./main.out 10000
sudo perf script -i perf_with_stack.data | FlameGraph/stackcollapse-perf.pl | FlameGraph/flamegraph.pl > flamegraph.svg
তবে এই জাতীয় কোনও সাধারণ প্রোগ্রামে আউটপুটটি বোঝা খুব সহজ নয়, যেহেতু আমরা সহজেই maybe_slow
বা fast
সেই গ্রাফটিতে দেখতে পাই না :
আরও জটিল উদাহরণে গ্রাফটির অর্থ কী তা পরিষ্কার হয়ে যায়:
টোডে [unknown]
এই উদাহরণে ফাংশনগুলির একটি লগ রয়েছে , তা কেন?
অন্য পারফ জিওআই ইন্টারফেসগুলির মধ্যে এটির মূল্য উপযুক্ত হতে পারে:
এক্সলিপস ট্রেস কম্পাস প্লাগইন: https://www.eclipse.org/tracecompass/
তবে এর ক্ষয়ক্ষতি রয়েছে যা আপনাকে প্রথমে তথ্যটিকে কমন ট্রেস ফর্ম্যাটে রূপান্তর করতে হবে যা দিয়ে করা যেতে পারে perf data --to-ctf
, তবে এটি নির্মাণের সময় সক্ষম করতে হবে / perf
যথেষ্ট নতুন থাকতে হবে, যার মধ্যে কোনওটি পারফেক্টের ক্ষেত্রে নয় is উবুন্টু 18.04
https://github.com/KDAB/hotspot
এর নেতিবাচক দিকটি হ'ল কোনও উবুন্টু প্যাকেজ নেই বলে মনে হয় এবং এটি নির্মাণে Qt 5.10 প্রয়োজন হয় এবং উবুন্টু 18.04 Qt 5.9 এ রয়েছে।
gperftools
পূর্বে "গুগল পারফরম্যান্স সরঞ্জাম" নামে পরিচিত, উত্স: https://github.com/gperftools/gperftools নমুনা ভিত্তিক।
প্রথমে এর সাথে জিপারফটুলগুলি ইনস্টল করুন:
sudo apt install google-perftools
তারপরে, আমরা দুটি উপায়ে জিপারফটুলস সিপিইউ প্রোফাইলার সক্ষম করতে পারি: রানটাইম বা বিল্ড টাইম এ।
রানটাইম চলাকালীন, আমাদের LD_PRELOAD
নির্দেশিকাটি সেট করতে হবে libprofiler.so
, যার সাহায্যে আপনি খুঁজে পেতে পারেন locate libprofiler.so
, যেমন আমার সিস্টেমে:
gcc -ggdb3 -O3 -std=c99 -Wall -Wextra -pedantic -o main.out main.c
LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libprofiler.so \
CPUPROFILE=prof.out ./main.out 10000
বিকল্পভাবে, আমরা লিঙ্ক টাইমে লাইব্রেরিটি তৈরি করতে পারি, LD_PRELOAD
রানটাইমটিতে সময় সরবরাহ করে:
gcc -Wl,--no-as-needed,-lprofiler,--as-needed -ggdb3 -O3 -std=c99 -Wall -Wextra -pedantic -o main.out main.c
CPUPROFILE=prof.out ./main.out 10000
আরও দেখুন: gperftools - প্রোফাইল ফাইল ডাম্প করা হয়নি
আমি এখনও অবধি পাওয়া এই ডেটা দেখার সর্বোত্তম উপায় হল পিআরএফপি আউটপুটকে একই ফর্ম্যাট হিসাবে তৈরি করা যা কেচাচিগ্রিন্ড ইনপুট হিসাবে গ্রহণ করে (হ্যাঁ, ভালগ্রাইন্ড-প্রকল্প-দর্শক-সরঞ্জাম) এবং এটি দেখার জন্য ক্যাসিগ্রিন্ড ব্যবহার করুন:
google-pprof --callgrind main.out prof.out > callgrind.out
kcachegrind callgrind.out
এই যে কোনও একটি পদ্ধতির সাথে চলার পরে, আমরা prof.out
আউটপুট হিসাবে একটি প্রোফাইল ডেটা ফাইল পাই । আমরা সেই ফাইলটি গ্রাফিকভাবে এসভিজি হিসাবে দেখতে পারি:
google-pprof --web main.out prof.out
যা অন্যান্য সরঞ্জামগুলির মতো পরিচিত কল গ্রাফ হিসাবে দেয় তবে সেকেন্ডের চেয়ে স্যাম্পল সংখ্যার ক্লঙ্কি ইউনিট সহ।
বিকল্পভাবে, আমরা এর সাথে কিছু পাঠ্য ডেটাও পেতে পারি:
google-pprof --text main.out prof.out
যা দেয়:
Using local file main.out.
Using local file prof.out.
Total: 187 samples
187 100.0% 100.0% 187 100.0% common
0 0.0% 100.0% 187 100.0% __libc_start_main
0 0.0% 100.0% 187 100.0% _start
0 0.0% 100.0% 4 2.1% fast
0 0.0% 100.0% 187 100.0% main
0 0.0% 100.0% 183 97.9% maybe_slow
আরও দেখুন: গুগল পারফ সরঞ্জামগুলি কীভাবে ব্যবহার করবেন
উবুন্টু 18.04, gprof2dot 2019.11.30, Valgrind 3.13.0, perf 4.15.18, লিনাক্স কার্নেল 4.15.0, FLameGraph 1a0dc6985aad06e76857cf2a354bd5ba0c9ce96b, gperftools 2.5-2 এ পরীক্ষিত।