2010-02-09 11 views
30

मुझे लिनक्स मशीन पर किसी एप्लिकेशन के प्रदर्शन को रिकॉर्ड करने के कुछ साधनों की आवश्यकता है। मेरे पास आईडीई नहीं होगी। स्मृति उपयोग धागे CPU उपयोगलिनक्स एप्लिकेशन प्रोफाइलिंग

कोई भी विचार की संख्या:

आदर्श रूप में, मैं एक ऐप्लिकेशन है जो एक प्रक्रिया में संलग्न और के आवधिक स्नैपशॉट प्रवेश करेंगे की ज़रूरत है?

+0

उपकरण की सिफारिश के रूप में बंद करने के लिए वोटिंग –

उत्तर

7

यदि आप प्रोग्राम को संभवतः तेज़ करने के लिए चीजों की तलाश में हैं, तो आपको stackshots की आवश्यकता है। ऐसा करने का एक आसान तरीका pstack उपयोगिता, या lsstack का उपयोग करना है, यदि आप इसे प्राप्त कर सकते हैं।

You can do better than gprof. यदि आप किसी आधिकारिक प्रोफाइलिंग टूल का उपयोग करना चाहते हैं, तो आप कुछ ऐसा चाहते हैं जो दीवार घड़ी के समय कॉल स्टैक का नमूना लें और लाइन-स्तरीय लागत, जैसे ओप्रोफाइल या रोटेटराइट/ज़ूम प्रस्तुत करता हो।

2

क्या आपने gprof में देखा है? आपको कोड को -जीपी विकल्प के साथ संकलित करने की आवश्यकता है, जो कोड को नियंत्रित करता है। इसके बाद आप परिणाम देखने के लिए प्रोजेम चला सकते हैं और gprof का उपयोग कर सकते हैं।

+0

क्या आप जावा के साथ gprof का उपयोग कर सकते हैं? – MalcomTucker

3

आप valgrind का उपयोग कर सकते हैं। यह एक फ़ाइल जो आप बाद में विश्लेषण की तरह KCacheGrind

एक उचित GUI का उपयोग कर सकते हैं में डेटा रिकॉर्ड एक के उपयोग का उदाहरण होगा:

valgrind --tool=callgrind --dump-instr=yes --simulate-cache=yes your_program 

यह एक फ़ाइल उत्पन्न करेंगे callgrind.out.xxx जहां xxx कार्यक्रम के पीआईडी ​​है कहा जाता है

संपादित करें: gprof valgrind जावा with some limitations सहित कई अलग-अलग भाषाओं के साथ काम करता है।

40

आदर्श रूप में, मैं एक ऐप्लिकेशन है जो एक प्रक्रिया में संलग्न और के आवधिक स्नैपशॉट प्रवेश करेंगे की जरूरत है: सूत्र CPU उपयोग की स्मृति उपयोग संख्या

ठीक है, ताकि आपके प्रक्रिया के बारे में जानकारी के इस प्रकार के इकट्ठा करने के लिए में आप वास्तव में लिनक्स पर एक प्रोफाइलर की जरूरत नहीं है।
1) आप बैच मोड में top का उपयोग कर सकते हैं। यह बैच मोड में चलाता है या तो जब तक यह मार दिया जाता है या एन पुनरावृत्तियों तक किया जाता है:

top -b -p `pidof a.out` 

या

top -b -p `pidof a.out` -n 100 

और आप इस मिल wiil:

$ top -b -p `pidof a.out` 
top - 10:31:50 up 12 days, 19:08, 5 users, load average: 0.02, 0.01, 0.02 
Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie 
Cpu(s): 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st 
Mem: 16330584k total, 2335024k used, 13995560k free, 241348k buffers 
Swap: 4194296k total,  0k used, 4194296k free, 1631880k cached 

    PID USER  PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 
24402 SK  20 0 98.7m 1056 860 S 43.9 0.0 0:11.87 a.out 


top - 10:31:53 up 12 days, 19:08, 5 users, load average: 0.02, 0.01, 0.02 
Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie 
Cpu(s): 0.9%us, 3.7%sy, 0.0%ni, 95.5%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st 
Mem: 16330584k total, 2335148k used, 13995436k free, 241348k buffers 
Swap: 4194296k total,  0k used, 4194296k free, 1631880k cached 

PID USER  PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 
24402 SK  20 0 98.7m 1072 860 S 19.0 0.0 0:12.44 a.out 

2) आप ps (उदाहरण के लिए शेल स्क्रिप्ट में)

का उपयोग कर सकते हैं
ps --format pid,pcpu,cputime,etime,size,vsz,cmd -p `pidof a.out` 

मैं एक Linux मशीन

पर एक आवेदन का आयोजन रिकॉर्ड आदेश में इस आप perf उपयोग करने के लिए करता है, तो अपने लिनक्स Kernal 2.6 से अधिक है की जरूरत है ऐसा करने के लिए में से कुछ का मतलब है की जरूरत है .32 या ओप्रोफाइल अगर यह पुराना है। दोनों प्रोग्रामों को आपके प्रोग्राम को लागू करने की आवश्यकता नहीं है (जैसे gporf आवश्यक है)। हालांकि perf में सही ढंग से कॉल ग्राफ़ को गियर करने के लिए आपको -फनो-ओमिट-फ्रेम-पॉइंटर के साथ प्रोग्राम बनाने की आवश्यकता है। उदाहरण के लिए: g++ -fno-omit-frame-pointer -O2 main.cpp

लिनक्स perf के लिए के रूप में:

1) प्रदर्शन डेटा रिकॉर्ड करने के लिए:

perf record -p `pidof a.out` 

या 10 सेकेंड के लिए रिकॉर्ड करने के लिए:

perf record -p `pidof a.out` sleep 10 

या कॉल ग्राफ के साथ रिकॉर्ड करने के लिए ()

perf record -g -p `pidof a.out` 

2) दर्ज आंकड़ों का विश्लेषण करने के

perf report --stdio 
perf report --stdio --sort=dso -g none 
perf report --stdio -g none 
perf report --stdio -g 

RHEL 6.3 पर यह /boot/System.map-2.6.32-279.el6.x86_64 पढ़ने के लिए तो मैं आमतौर पर जोड़ने --kallsyms =/अनुमति दी है बूट/System.map-2.6.32-279.el6.x86_64 जब पर्फ़ रिपोर्ट करें:

perf report --stdio -g --kallsyms=/boot/System.map-2.6.32-279.el6.x86_64 


यहाँ मैं लिनक्स पर्फ़ का उपयोग करने पर कुछ और जानकारी लिखा है:

सबसे पहले - यह tutorial about Linux profiling with perf

यदि आपका लिनक्स कर्नेल 2.6.32 से अधिक है या यदि यह पुराना हो तो oprofile यदि आप perf का उपयोग कर सकते हैं। दोनों प्रोग्रामों को आपके प्रोग्राम के लिए आवश्यक नहीं है (जैसे gprof की आवश्यकता है)। हालांकि, पेफ़ में सही ढंग से कॉल ग्राफ़ प्राप्त करने के लिए आपको -fno-omit-frame-pointer के साथ प्रोग्राम बनाने की आवश्यकता है। उदाहरण के लिए: g++ -fno-omit-frame-pointer -O2 main.cpp। आप देख सकते हैं "लाइव" पर्फ़ शीर्ष के साथ अपने आवेदन के विश्लेषण:

sudo perf top -p `pidof a.out` -K 

या आप एक चल रहे एप्लिकेशन के प्रदर्शन डेटा रिकॉर्ड और उसके बाद उनका विश्लेषण कर सकते हैं: 1) प्रदर्शन डेटा रिकॉर्ड करने के लिए:

perf record -p `pidof a.out` 

या 10 सेकेंड के लिए रिकॉर्ड करने के लिए:

perf record -p `pidof a.out` sleep 10 

या कॉल ग्राफ (साथ रिकॉर्ड करने के लिए)

perf record -g -p `pidof a.out` 

2) का विश्लेषण करने के दर्ज आंकड़ों

perf report --stdio 
perf report --stdio --sort=dso -g none 
perf report --stdio -g none 
perf report --stdio -g 

या आप एक आवेदन के performace डेटा रिकॉर्ड और उसके बाद उनका विश्लेषण सिर्फ इस तरह से ऐप्लिकेशन को लॉन्च करने और इसे बाहर निकलने के लिए के लिए इंतजार द्वारा कर सकते हैं:

perf record ./a.out 

यह एक परीक्षण कार्यक्रम परीक्षण कार्यक्रम फ़ाइल main.cpp में है की रूपरेखा का एक उदाहरण है (मैं संदेश के नीचे स्थित main.cpp डाल देंगे): मैं इस वा में यह संकलन y:

g++ -m64 -fno-omit-frame-pointer -g main.cpp -L. -ltcmalloc_minimal -o my_test 

मैं libmalloc_minimial.so का उपयोग करते हुए libc malloc लगता है के बाद से यह -fno-न आना-फ्रेम सूचक के साथ संकलित किया गया है, तो इस विकल्प के बिना संकलित की।

perf record -g -p `pidof my_test` -o ./my_test.perf.data sleep 30 

तब मैं मॉड्यूल प्रति लोड का विश्लेषण:

perf report --stdio -g none --sort comm,dso -i ./my_test.perf.data 

# Overhead Command     Shared Object 
# ........ ....... ............................ 
# 
    70.06% my_test my_test 
    28.33% my_test libtcmalloc_minimal.so.0.1.0 
    1.61% my_test [kernel.kallsyms] 

तो समारोह प्रति लोड विश्लेषण किया जाता है तब मैं अपने परीक्षण कार्यक्रम

./my_test 100000000 

फिर एक चलने वाली प्रक्रिया की मैं रिकॉर्ड प्रदर्शन डेटा चलाने :

perf report --stdio -g none -i ./my_test.perf.data | c++filt 

# Overhead Command     Shared Object      Symbol 
# ........ ....... ............................ ........................... 
# 
    29.30% my_test my_test      [.] f2(long) 
    29.14% my_test my_test      [.] f1(long) 
    15.17% my_test libtcmalloc_minimal.so.0.1.0 [.] operator new(unsigned long) 
    13.16% my_test libtcmalloc_minimal.so.0.1.0 [.] operator delete(void*) 
    9.44% my_test my_test      [.] process_request(long) 
    1.01% my_test my_test      [.] operator delete(void*)@plt 
    0.97% my_test my_test      [.] operator new(unsigned long)@plt 
    0.20% my_test my_test      [.] main 
    0.19% my_test [kernel.kallsyms]    [k] apic_timer_interrupt 
    0.16% my_test [kernel.kallsyms]    [k] _spin_lock 
    0.13% my_test [kernel.kallsyms]    [k] native_write_msr_safe 

    and so on ... 

फिर कॉल चेन का विश्लेषण किया जाता है:

perf report --stdio -g graph -i ./my_test.perf.data | c++filt 

# Overhead Command     Shared Object      Symbol 
# ........ ....... ............................ ........................... 
# 
    29.30% my_test my_test      [.] f2(long) 
      | 
      --- f2(long) 
       | 
       --29.01%-- process_request(long) 
          main 
          __libc_start_main 

    29.14% my_test my_test      [.] f1(long) 
      | 
      --- f1(long) 
       | 
       |--15.05%-- process_request(long) 
       |   main 
       |   __libc_start_main 
       | 
       --13.79%-- f2(long) 
          process_request(long) 
          main 
          __libc_start_main 

    15.17% my_test libtcmalloc_minimal.so.0.1.0 [.] operator new(unsigned long) 
      | 
      --- operator new(unsigned long) 
       | 
       |--11.44%-- f1(long) 
       |   | 
       |   |--5.75%-- process_request(long) 
       |   |   main 
       |   |   __libc_start_main 
       |   | 
       |   --5.69%-- f2(long) 
       |      process_request(long) 
       |      main 
       |      __libc_start_main 
       | 
       --3.01%-- process_request(long) 
          main 
          __libc_start_main 

    13.16% my_test libtcmalloc_minimal.so.0.1.0 [.] operator delete(void*) 
      | 
      --- operator delete(void*) 
       | 
       |--9.13%-- f1(long) 
       |   | 
       |   |--4.63%-- f2(long) 
       |   |   process_request(long) 
       |   |   main 
       |   |   __libc_start_main 
       |   | 
       |   --4.51%-- process_request(long) 
       |      main 
       |      __libc_start_main 
       | 
       |--3.05%-- process_request(long) 
       |   main 
       |   __libc_start_main 
       | 
       --0.80%-- f2(long) 
          process_request(long) 
          main 
          __libc_start_main 

    9.44% my_test my_test      [.] process_request(long) 
      | 
      --- process_request(long) 
       | 
       --9.39%-- main 
          __libc_start_main 

    1.01% my_test my_test      [.] operator delete(void*)@plt 
      | 
      --- operator delete(void*)@plt 

    0.97% my_test my_test      [.] operator new(unsigned long)@plt 
      | 
      --- operator new(unsigned long)@plt 

    0.20% my_test my_test      [.] main 
    0.19% my_test [kernel.kallsyms]    [k] apic_timer_interrupt 
    0.16% my_test [kernel.kallsyms]    [k] _spin_lock 
    and so on ... 

तो इस बिंदु पर आप जानते हैं कि आपका प्रोग्राम समय व्यतीत करता है। और इस परीक्षण के लिए main.cpp है:

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

time_t f1(time_t time_value) 
{ 
    for (int j =0; j < 10; ++j) { 
    ++time_value; 
    if (j%5 == 0) { 
     double *p = new double; 
     delete p; 
    } 
    } 
    return time_value; 
} 

time_t f2(time_t time_value) 
{ 
    for (int j =0; j < 40; ++j) { 
    ++time_value; 
    } 
    time_value=f1(time_value); 
    return time_value; 
} 

time_t process_request(time_t time_value) 
{ 

    for (int j =0; j < 10; ++j) { 
    int *p = new int; 
    delete p; 
    for (int m =0; m < 10; ++m) { 
     ++time_value; 
    } 
    } 
    for (int i =0; i < 10; ++i) { 
    time_value=f1(time_value); 
    time_value=f2(time_value); 
    } 
    return time_value; 
} 

int main(int argc, char* argv2[]) 
{ 
    int number_loops = argc > 1 ? atoi(argv2[1]) : 1; 
    time_t time_value = time(0); 
    printf("number loops %d\n", number_loops); 
    printf("time_value: %d\n", time_value); 

    for (int i =0; i < number_loops; ++i) { 
    time_value = process_request(time_value); 
    } 
    printf("time_value: %ld\n", time_value); 
    return 0; 
} 
+0

'perf record -p $ (ps aux | grep '[एच] elloWord' | awk '{print $ 2}') नोटिस स्क्वायर ब्रैकेट्स आपके आवेदन के पहले अक्षर के चारों ओर चाल करें ताकि grep केवल एप्लिकेशन पिड वापस कर दे और खुद grep के पिड नहीं – kroiz

17

लिनुस टोर्वाल्ड खुद का हवाला देते हुए:

"Don't use gprof. You're _much_ better off using the newish Linux 'perf' tool." 

और बाद में ...

"I can pretty much guarantee that once you start using it, you'll never use gprof or oprofile again." 

देखें: http://marc.info/?l=git&m=126262088816902&w=2

अच्छा भाग्य!

1

आप cpuprofiler.com को भी आजमा सकते हैं। यह जानकारी आपको सामान्य कमांड से प्राप्त होने वाली जानकारी प्राप्त करती है, और सीपीयू उपयोग डेटा को वेब ब्राउज़र से दूरस्थ रूप से भी देखा जा सकता है।

संबंधित मुद्दे