ग्रेफ़िक के विकल्प [बंद]


166

क्या अन्य कार्यक्रम समान रूप से समान हैं?


2
आप किन प्लेटफार्मों में रुचि रखते हैं?
ऑक्सक्स

2
मुझे लिनक्स में दिलचस्पी है।
न्यूरोमेंसर


13
@ ग्रेगरी - मैं सहमत होने के लिए इच्छुक हूं, और शायद उसे अपने खुद के 229 बनाम 6 के जवाब के साथ योगदान करना चाहिए, उन सभी 6 में से 6 जवाब उसके अपने सवालों के हैं ...
जीन-बर्नार्ड पेलरिन

5
यह प्रश्न रचनात्मक कैसे नहीं हो सकता है?
जॉनटोर्टुगो

जवाबों:


73

Valgrind में एक बहुत अच्छा विज़ुअलाइज़र है जिसमें KCacheGrind नामक एक निर्देश-गिनती प्रोफाइलर है । जैसा कि माइक डनलवे ने सिफारिश की है, वाल्ग्रिंड उन निर्देशों का अंश गिनाता है जिसके लिए एक प्रक्रिया स्टैक पर रहती है, हालांकि मुझे यह कहने के लिए खेद है कि यह पारस्परिक पुनरावृत्ति की उपस्थिति में भ्रमित हो जाता है। लेकिन विज़ुअलाइज़र बहुत अच्छा है और प्रकाश वर्ष आगे है gprof


2
@ नोर्मन: ++ रिकर्सन के बारे में यह भ्रम उन प्रणालियों के लिए स्थानिक है जो एक ग्राफ में नोड्स के बीच कई बार प्रचार करने की अवधारणा रखते हैं। इसके अलावा, मुझे लगता है कि दीवार-घड़ी का समय आमतौर पर सीपीयू अनुदेश समय की तुलना में अधिक उपयोगी होता है, और कोड लाइनें (कॉल निर्देश) प्रक्रियाओं की तुलना में अधिक उपयोगी होती हैं। यदि यादृच्छिक दीवार घड़ी समय पर स्टैक नमूने लिए जाते हैं, तो एक पंक्ति (या प्रक्रिया, या कोई अन्य विवरण जो आप कर सकते हैं) की आंशिक लागत का अनुमान केवल नमूनों के उस अंश से लगाया जाता है जो इसे प्रदर्शित करता है।
माइक डनलैवी

1
... मैं कॉल निर्देशों पर जोर दे रहा हूं, लेकिन यह किसी भी निर्देश पर लागू होता है। यदि किसी के पास एक ईमानदार-टू-गुडनेस हॉटस्पॉट टोंटी है, जैसे कि एक बड़े प्रकार की संख्याओं का बुलबुला प्रकार है, तो आंतरिक लूप की तुलना / कूद / स्वैप / वेतन वृद्धि निर्देश लगभग हर स्टैक नमूने के शीर्ष / तल पर होगा। । लेकिन (विशेष रूप से सॉफ्टवेयर बड़ा हो जाता है और शायद ही कोई दिनचर्या बहुत "स्व" समय होती है) कई समस्याएं वास्तव में कॉल निर्देश हैं, काम का अनुरोध करते हुए, जब यह स्पष्ट है कि इसकी लागत कितनी है, तो वास्तव में ऐसा करने की आवश्यकता नहीं है।
माइक डनलैवी

3
... इसकी जांच करें। मुझे लगता है कि वे लगभग सही रास्ते पर हैं: rotateright.com/zoom.html
माइक डनलैवी

195

ऐतिहासिक कारणों से ग्रिफ़िट (पेपर पढ़ें) मौजूद है। यदि आपको लगता है कि यह प्रदर्शन समस्याओं को खोजने में आपकी सहायता करेगा, तो इसे कभी भी विज्ञापित नहीं किया गया था। यहाँ कागज क्या कहता है:

प्रो costs ले का उपयोग विभिन्न कार्यान्वयनों की लागतों की तुलना और आकलन करने के लिए किया जा सकता है।

यह नहीं कहता है कि इसका उपयोग विभिन्न कार्यान्वयनों की पहचान करने के लिए किया जा सकता है, हालांकि इसका मतलब यह है कि यह विशेष परिस्थितियों में हो सकता है:

खासकर अगर कार्यक्रम के छोटे हिस्से अपने निष्पादन समय पर हावी पाए जाते हैं।

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

इसके बजाय यह प्रयास करें।
यहां 44x स्पीडअप का उदाहरण दिया गया है।
यहां 730x स्पीडअप दिया गया है।
यहां 8 मिनट का वीडियो प्रदर्शन है।
यहाँ आँकड़ों की एक व्याख्या है।
यहां आलोचकों का जवाब है।

कार्यक्रमों के बारे में एक साधारण अवलोकन है। किसी दिए गए निष्पादन में, प्रत्येक निर्देश समग्र समय (विशेष रूप से callनिर्देश) के कुछ अंश के लिए जिम्मेदार होता है , इस अर्थ में कि यदि यह नहीं होता, तो समय व्यतीत नहीं होता। उस समय के दौरान, निर्देश स्टैक ** पर है। जब यह समझा जाता है, तो आप देख सकते हैं कि -

प्रदर्शन के बारे में कुछ मिथकों का विरोध करता है, जैसे:

  1. यह प्रोग्राम काउंटर सैंपलिंग उपयोगी है।
    यह केवल तभी उपयोगी है जब आपके पास अनावश्यक हॉटस्पॉट अड़चन हो जैसे कि बड़े आकार के स्केलर मानों का बुलबुला। जैसे ही आप, उदाहरण के लिए, इसे स्ट्रिंग-तुलना का उपयोग करके सॉर्ट में बदलते हैं, यह अभी भी एक अड़चन है, लेकिन प्रोग्राम काउंटर नमूनाकरण इसे नहीं देखेगा क्योंकि अब हॉटस्पॉट स्ट्रिंग-तुलना में है। दूसरी ओर अगर यह विस्तारित कार्यक्रम काउंटर (कॉल स्टैक) का नमूना लेने के लिए था , तो जिस बिंदु पर स्ट्रिंग-तुलना कहा जाता है, सॉर्ट लूप, स्पष्ट रूप से प्रदर्शित होता है। वास्तव में, पीसी-ओनली सैंपलिंग की सीमाओं को मापने के लिए ग्रेफाइट एक प्रयास था।

  2. कोड के समय लेने वाली लाइनों को कैप्चर करने से ज्यादा महत्वपूर्ण है टाइमिंग फंक्शन।
    उस मिथक का कारण यह है कि ग्रिफ़िट स्टैक नमूनों को कैप्चर करने में सक्षम नहीं था, इसलिए इसके बजाय यह कई बार कार्य करता है, अपने इनवोकेशन को गिनता है, और कॉल ग्राफ़ को पकड़ने की कोशिश करता है। हालांकि, एक बार एक महंगा कार्य की पहचान होने के बाद, आपको अभी भी इसके लिए लाइनों के अंदर देखना होगा जो समय के लिए जिम्मेदार हैं। यदि स्टैक नमूने थे तो आपको देखने की आवश्यकता नहीं होगी, वे लाइनें नमूनों पर होंगी। (एक विशिष्ट फ़ंक्शन में 100 - 1000 निर्देश हो सकते हैं। एक फ़ंक्शन कॉल 1 निर्देश है, इसलिए महंगा कॉल करने वाले स्थान को परिमाण के 2-3 आदेश अधिक सटीक हैं।)

  3. कॉल ग्राफ महत्वपूर्ण है।
    आपको एक कार्यक्रम के बारे में जानने की आवश्यकता नहीं है कि वह अपना समय कहाँ बिताता है, लेकिन क्यों। जब यह किसी फ़ंक्शन में समय बिता रहा होता है, तो स्टैक पर कोड की प्रत्येक पंक्ति तर्क की श्रृंखला में एक लिंक देती है कि यह वहां क्यों है। यदि आप केवल स्टैक का हिस्सा देख सकते हैं, तो आप केवल कारण का हिस्सा देख सकते हैं, इसलिए आप यह सुनिश्चित करने के लिए नहीं बता सकते हैं कि क्या वास्तव में समय आवश्यक है। कॉल ग्राफ़ आपको क्या बताता है? प्रत्येक चाप आपको बताता है कि कुछ फ़ंक्शन A उस समय के कुछ अंश के लिए कुछ फ़ंक्शन B को कॉल करने की प्रक्रिया में था। यहां तक ​​कि अगर A के पास B को कॉल करने की केवल एक ही पंक्ति है, तो वह रेखा केवल कारण का एक छोटा हिस्सा देती है। यदि आप पर्याप्त भाग्यशाली हैं, तो शायद उस रेखा का खराब कारण है। आमतौर पर, आपको एक गरीब कारण खोजने के लिए एक साथ कई लाइनें देखने की आवश्यकता होती है यदि यह वहां है। यदि A, B को एक से अधिक स्थानों पर बुलाता है, तो यह आपको और भी कम बताता है।

  4. यह पुनरावृत्ति एक पेचीदा भ्रमित करने वाला मुद्दा है।
    यह केवल इसलिए है क्योंकि गैर - लाभकारी और अन्य प्रोफाइलर कॉल-ग्राफ बनाने की आवश्यकता महसूस करते हैं और फिर नोड्स के लिए विशेषता रखते हैं। यदि किसी के पास ढेर के नमूने हैं, तो नमूनों पर दिखाई देने वाली कोड की प्रत्येक पंक्ति की समय-लागत एक बहुत ही सरल संख्या है - नमूनों का वह अंश जो चालू है। यदि पुनरावृत्ति होती है, तो एक दी गई रेखा एक नमूने पर एक से अधिक बार दिखाई दे सकती है। कोई बात नहीं। मान लीजिए कि नमूने प्रत्येक एन एमएस पर लिए गए हैं, और लाइन उनमें से एफ% (अकेले या नहीं) पर दिखाई देती है। यदि उस रेखा को बिना समय लगने के लिए बनाया जा सकता है (जैसे कि इसे हटाकर या इसके चारों ओर शाखा लगाकर), तो वे नमूने गायब हो जाएंगे , और समय F% से कम हो जाएगा।

  5. समय की माप की सटीकता (और इसलिए बड़ी संख्या में नमूने) महत्वपूर्ण हैं।
    इसके बारे में एक सेकंड सोचें। यदि कोड की एक पंक्ति पांच में से 3 नमूनों पर है, तो यदि आप इसे एक प्रकाश बल्ब की तरह शूट कर सकते हैं, तो इसका उपयोग लगभग 60% कम समय होता है। अब, आप जानते हैं कि यदि आपने अलग-अलग 5 नमूने लिए थे, तो आप इसे केवल 2 बार देख सकते हैं, या 4 के रूप में कई। ताकि 60% माप 40% से 80% तक सामान्य श्रेणी की तरह अधिक हो। यदि यह केवल 40% थे, तो क्या आप कहेंगे कि समस्या ठीक होने के लायक नहीं है? तो समय की सटीकता की बात क्या है, जब आप वास्तव में चाहते हैं कि समस्याओं का पता लगाना है ? 500 या 5000 नमूनों ने अधिक सटीकता के साथ समस्या को मापा होगा, लेकिन इसे और अधिक सटीक रूप से नहीं पाया होगा।

  6. कथन या फ़ंक्शन इनवोकेशन की गिनती उपयोगी है।
    मान लीजिए कि आप जानते हैं कि किसी फंक्शन को 1000 बार बुलाया गया है। क्या आप बता सकते हैं कि समय का कितना भाग खर्च होता है? आपको यह भी जानना होगा कि चलने में कितना समय लगता है, औसतन, इसे गिनती से गुणा करें और कुल समय से विभाजित करें। औसत आह्वान का समय नैनोसेकंड से सेकंड तक भिन्न हो सकता है, इसलिए अकेले गिनती ज्यादा नहीं बताती है। यदि स्टैक नमूने हैं, तो एक रूटीन या किसी भी स्टेटमेंट की लागत केवल उन नमूनों का अंश है जो उस पर है। समय का वह अंश जो सिद्धांत रूप में बचाया जा सकता है, यदि दिनचर्या या कथन को बिना समय के लिया जा सकता है, तो प्रदर्शन का सबसे सीधा संबंध यही है।

  7. अवरुद्ध होने पर नमूनों की आवश्यकता नहीं होती है
    । इस मिथक के कारण दो गुना हैं: 1) जब पीसी प्रतीक्षा कर रहा होता है, तो यह व्यर्थ होता है, और 2) समय की सटीकता के साथ पूर्वाग्रह। हालाँकि, कार्यक्रम के लिए (1) बहुत अच्छी तरह से उस चीज का इंतजार किया जा सकता है जो उसने मांगी थी, जैसे कि फ़ाइल I / O, जिसे आपको जानना आवश्यक है , और जो स्टैक नमूने प्रकट करते हैं। (जाहिर है कि आप उपयोगकर्ता इनपुट की प्रतीक्षा करते समय नमूनों को बाहर करना चाहते हैं।) (2) यदि प्रोग्राम अन्य प्रक्रियाओं के साथ प्रतिस्पर्धा के कारण बस इंतजार कर रहा है, तो संभवतः यह एक यादृच्छिक तरीके से चल रहा है जबकि यह चल रहा है। इसलिए, जबकि कार्यक्रम में अधिक समय लग सकता है, इससे स्टेटमेंट पर बहुत अधिक प्रभाव नहीं पड़ेगा जो मायने रखता है, स्टेटमेंट का समय स्टैक पर है।

  8. यह "सेल्फ टाइम" मायने रखता है।
    सेल्फ टाइम केवल तभी समझ में आता है जब आप फंक्शन लेवल पर माप रहे हैं, न कि लाइन लेवल पर, और आपको लगता है कि फंक्शन का समय विशुद्ध रूप से लोकल कंपीटिशन वर्सेस कहलाने वाले रूटीन में हो जाता है। यदि रेखा के स्तर पर संक्षेप में, एक पंक्ति स्व समय का प्रतिनिधित्व करती है यदि यह स्टैक के अंत में है, अन्यथा यह समावेशी समय का प्रतिनिधित्व करता है। किसी भी तरह से, इसकी लागत क्या है यह स्टैक नमूनों का प्रतिशत है, इस पर यह किसी भी स्थिति में आपके लिए है।

  9. उस नमूने को उच्च आवृत्ति पर लिया जाना चाहिए।
    यह इस विचार से आता है कि एक प्रदर्शन समस्या तेजी से काम कर सकती है, और इसे हिट करने के लिए नमूनों को लगातार होना पड़ता है। लेकिन, यदि समस्या की लागत 20% है, तो कहें, 10 सेकंड (या जो भी) के कुल चल रहे समय में से, तो उस कुल समय में प्रत्येक नमूने को मारने की 20% संभावना होगी, समस्या होने पर कोई फर्क नहीं पड़ता इस तरह के एक टुकड़े में
    .....XXXXXXXX...........................
    .^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^(20 नमूने, 4 हिट)
    या इस तरह के कई छोटे टुकड़ों में
    X...X...X.X..X.........X.....X....X.....
    .^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^(20 नमूने, 3 हिट)
    किसी भी तरह, हिट की संख्या औसतन 5 में औसतन होगी, चाहे कितने नमूने लिए जाएं, या कितना कुछ। (औसत: 20 * 0.2 = 4. मानक विचलन = +/- sqrt (20 * 0.2 * 0.8) = 1.8)।

  10. कि तुम अड़चन खोजने की कोशिश कर रहे हो जैसे कि
    एक ही हो। निम्नलिखित निष्पादन समयरेखा पर विचार करें: vxvWvzvWvxvWvYvWvxvWv.vWvxvWvYvW
    इसमें वास्तविक उपयोगी कार्य शामिल हैं, जिनके द्वारा प्रतिनिधित्व किया गया है .vWxYzक्रमशः 1/2, 1/4, 1/8, 1/16, 1/32 समय लेकर प्रदर्शन समस्याएं हैं। नमूना vआसानी से मिल जाता है। इसे हटा दिया जाता है,
    xWzWxWYWxW.WxWYW
    अब प्रोग्राम को चलाने में Wआधा समय लगता है , और अब आधा समय लगता है, और आसानी से मिल जाता है। इसे हटा दिया जाता है,
    xzxYx.xY
    यह प्रक्रिया जारी रहती है, हर बार सबसे बड़ी, प्रतिशत, प्रदर्शन की समस्या को दूर करने तक, जब तक हटाने के लिए कुछ भी नहीं मिल सकता है। अब निष्पादित केवल एक चीज है ., जो मूल कार्यक्रम द्वारा उपयोग किए गए समय के 1/32 में निष्पादित होती है। यह आवर्धन प्रभाव है, जिससे किसी भी समस्या को हटाकर शेष को प्रतिशत से बड़ा किया जाता है, क्योंकि हर को कम किया जाता है।
    एक और महत्वपूर्ण बिंदु यह है कि हर एक समस्या को ढूंढना होगा - 5 में से कोई भी लापता नहीं है। कोई भी समस्या नहीं मिली है और निश्चित रूप से अंतिम स्पीडअप अनुपात को कम करती है। बस कुछ ढूंढना, लेकिन सभी नहीं, "पर्याप्त पर्याप्त" नहीं है।

जोड़े गए: मैं होगा सिर्फ एक कारण बाहर बात करने के लिए की तरह क्यों gprof लोकप्रिय है - यह पढ़ाया जा रहा है जा रहा है, शायद क्योंकि यह मुफ़्त है, आसान सिखाने के लिए है, और यह एक लंबे समय के आसपास हो गया है। एक त्वरित Google खोज कुछ शैक्षणिक संस्थानों को सिखाती है जो इसे सिखाते हैं (या प्रकट होते हैं):

बर्कले बू क्लेम्सन कोलोरेडो ड्यूक ईयरलैम फ्सु इंडियाना माइट मस्क ncsa.illipedia ncsu nyu ou प्रिंसटन पोस स्टैनफोर्ड ucsd umd यूमिच यूटा यूक्सैक्स यूस्ट वेसल

** काम करने का अनुरोध करने के अन्य तरीकों, कि एक का पता लगाने कह नहीं छोड़ते के अपवाद के साथ क्यों इस तरह के संदेश पोस्ट किए जाने के रूप में,।


3
@ नोर्मन: मैंने इस पर आधारित एक प्रोफाइलर बनाया, सी फॉर डीओएस में, '93 के आसपास। मैंने इसे अभी तक एक और प्रदर्शन-प्रदर्शन-विश्लेषक कहा, और इसे IEEE बैठकों में इसके आसपास डेमो किया, लेकिन यह उतना ही है जितना कि यह चला गया। रोटेटाइट से एक उत्पाद है जिसे ज़ूम कहा जाता है जो बहुत दूर नहीं है। * Nix पर, मैन्युअल रूप से करने के लिए pstack अच्छा है। काम के लिए मेरी टू-डू सूची (विंडोज पर फार्माकोमेट्रिक्स) लगभग एक मील लंबी है जो मजेदार परियोजनाओं को छोड़ती है, परिवार का उल्लेख नहीं करती है। यह उपयोगी हो सकता है: stackoverflow.com/questions/1777669/…
माइक डनलवे

6
मैंने हमेशा पाया कि धीमे कोड को ठीक करने के लिए प्रोफाइलर इतने उपयोगी नहीं हैं, और इसके बजाय मेरे चयन के वक्तव्यों के एक समूह द्वारा लिए गए समय को मापने के लिए डिबगिंग कोड के चयनात्मक बिट्स का उपयोग किया जाता है, अक्सर कुछ तुच्छ छोटे मैक्रोज़ या जो भी सहायता प्राप्त होती है। अपराधी को खोजने के लिए मुझे कभी भी बहुत लंबा समय नहीं लगा, लेकिन मैं हमेशा अपने "भालू की खाल और पत्थर के चाकू" के लिए शर्मिंदा रहा हूं जब "बाकी सब" (जहां तक ​​मुझे पता है) फैंसी टूल का उपयोग करता है। मुझे यह दिखाने के लिए धन्यवाद कि मुझे प्रोफाइलर से आवश्यक जानकारी कभी नहीं मिली। यह सबसे महत्वपूर्ण विचारों में से एक है जो मैंने एसओ पर देखा है। बहुत बढ़िया!
वेन कॉनराड

7
@osgx: मेरा मतलब किसी भी चीर-फाड़ से नहीं है। यह एक पुराने पसंदीदा ऑटोमोबाइल की तरह है, सरल और बीहड़, लेकिन ऐसी चीजें हैं जो ऐसा नहीं करती हैं, और हमें उन लोगों के बारे में पता होना चाहिए, और यही नहीं, हमें मिथकों से जागने की जरूरत है। मैं सराहना करता हूं कि कुछ प्लेटफार्मों पर स्टैक सैंपल प्राप्त करना मुश्किल हो सकता है, लेकिन अगर कोई समस्या ऐसी है, जिसमें ग्रिफ़िट इसे नहीं मिलेगा, तो यह तथ्य है कि यह एकमात्र उपकरण छोटा आराम है।
माइक डनलैवी

2
@Andrew: ... और यदि वह कारण नमूनों के कुछ महत्वपूर्ण अंशों (जैसे 1 से अधिक) पर लागू होता है, तो कोड की लाइन (s) जो उस गतिविधि को समाप्त कर सकती हैं, उन नमूनों पर हैं। एक ग्राफ आपको इस बात का संकेत दे सकता है , लेकिन एक बड़ी संख्या में ढेर के नमूने बस उन्हें आपको नहीं दिखाएंगे।
माइक डनलैवी

2
@ मैट: आईओ प्रदर्शन समस्याओं के उदाहरण इस प्रकार पाए गए: 1) लॉग संदेश को किसी फ़ाइल या कंसोल पर प्रिंट करना, जिसे गलत तरीके से महत्वहीन समझा गया था। 2) संख्यात्मक IO में पाठ और युगल के बीच रूपांतरण। 3) सबट्रेनियन आईओ स्टार्टअप के दौरान अंतर्राष्ट्रीयकृत तार निकालते हैं, यह पता चलता है कि इसे अंतर्राष्ट्रीयकरण करने की आवश्यकता नहीं है। मैंने इन जैसे बहुत से उदाहरण दिए हैं।
माइक डनलैवी

63

चूँकि मैंने यहाँ कुछ भी नहीं perfदेखा जिसके बारे में लिनक्स पर कर्नेल और उपयोगकर्ता अनुप्रयोगों की रूपरेखा के लिए एक अपेक्षाकृत नया उपकरण है, मैंने इस जानकारी को जोड़ने का फैसला किया।

सबसे पहले - यह लिनक्स प्रोफाइलिंग के बारे में एक ट्यूटोरियल हैperf

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

आप अपने आवेदन का "लाइव" विश्लेषण देख सकते हैं perf top:

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

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

perf record ./a.out

यह एक परीक्षण कार्यक्रम की रूपरेखा का एक उदाहरण है

परीक्षण कार्यक्रम फ़ाइल main.cpp में है (मैं संदेश के निचले भाग में main.cpp डालूँगा):

मैं इसे इस तरह संकलित करता हूं:

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

मैं उपयोग करता हूं libmalloc_minimial.soक्योंकि यह संकलित है -fno-omit-frame-pointerजबकि libc malloc इस विकल्प के बिना संकलित लगता है। फिर मैं अपना परीक्षण कार्यक्रम चलाता हूं

./my_test 100000000 

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

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

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

संपूर्ण रिपोर्ट --stdio-g कोई नहीं --sort कॉम, 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]

फिर लोड प्रति फ़ंक्शन का विश्लेषण किया जाता है:

संपूर्ण रिपोर्ट --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 ...

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

संपूर्ण रिपोर्ट --stdio -g ग्राफ -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;
}

मैंने सिर्फ आपका उदाहरण दिया और 5 स्टैकशॉट लिए। यहाँ उन्होंने पाया है: उस समय f1का 40% (मोटे तौर पर) फोन कर रहा था delete। समय का 40% (मोटे तौर पर) process_requestबुला रहा था delete। शेष का एक अच्छा हिस्सा खर्च किया गया था new। माप खुरदरे हैं, लेकिन आकर्षण के केंद्र हैं।
माइक डनलैवी

एक क्या है stackshot? क्या यह pstackआउटपुट है?

2
As in my answer, you run it under a debugger and hit ^C at a random time and capture the stack trace। 1) मुझे लगता है कि जब आपके ग्राहक के सर्वर पर चल रहे प्रोग्राम के लिए आपको प्रदर्शन समस्याओं का विश्लेषण करने की आवश्यकता होती है, तो आपकी तकनीक उपयोगी नहीं होती है। 2) मुझे यकीन नहीं है कि आप कैसे इस तकनीक को लागू करते हैं एक प्रोग्राम के लिए जानकारी प्राप्त करने के लिए बहुत सारे धागे हैं जो विभिन्न अनुरोधों को संभालते हैं। मेरा मतलब है जब सामान्य तस्वीर काफी जटिल है।

2
# 1 के लिए के रूप में। कभी-कभी ग्राहक कॉल करते हैं और कहते हैं कि आपका कार्यक्रम धीरे-धीरे काम करता है। आप तुरंत ऐसा नहीं कह the problem is outside your codeसकते, क्या आप कर सकते हैं? चूंकि आपको अपनी बात का समर्थन करने के लिए कुछ जानकारी की आवश्यकता हो सकती है। इस स्थिति में आपको कुछ बिंदु पर अपने आवेदन को प्रोफाइल करना पड़ सकता है। आप बस अपने ग्राहक को gdb शुरू करने और ^ C प्रेस करने और कॉल स्टैक प्राप्त करने के लिए नहीं कह सकते। यह मेरी बात थी। यह एक उदाहरण है spielwiese.fontein.de/2012/01/22/… । मुझे यह समस्या थी और प्रोफाइलिंग ने बहुत मदद की।

2
# 2 के लिए के रूप में। सरलीकरण एक अच्छा दृष्टिकोण है, मैं सहमत हूं। कभी-कभी यह काम करता है। यदि प्रदर्शन समस्या केवल ग्राहक के सर्वर पर होती है और आप उन्हें अपने सर्वर पर पुन: पेश नहीं कर सकते हैं तो प्रोफाइल उपयोग की है।

21

OProfile का प्रयास करें । यह आपके कोड को प्रोफाइल करने के लिए एक बेहतर उपकरण है। मैं Intel VTune का सुझाव भी दूंगा

उपरोक्त दो उपकरण कोड की एक विशेष लाइन में बिताए गए समय को कम कर सकते हैं, आपके कोड को एनोटेट कर सकते हैं, असेंबली दिखा सकते हैं और कितना विशेष निर्देश ले सकते हैं। समय मीट्रिक के अलावा, आप विशिष्ट काउंटर, यानी कैश हिट इत्यादि को भी क्वेरी कर सकते हैं।

गैर-लाभकारी के विपरीत, आप दोनों में से किसी का उपयोग करके अपने सिस्टम पर चलने वाली किसी भी प्रक्रिया / बाइनरी को प्रोफाइल कर सकते हैं।


2
जैसा कि वैलग्राइंड उत्तर में भी उल्लेख किया गया है, ज़ूम इन रोटेटाइट ( rotateright.com ) एक बहुत अच्छा इंटरफ़ेस प्रदान करता है और दूरस्थ रूपरेखा की अनुमति देता है।
जेनफेनी

ऑप्रोफाइल पसंद नहीं था, यह अजीब लग रहा था
मैट जॉइनर

@ कोई खास बात?
ऐकॉर्न

स्टेटफ्लो उत्पन्न करने से पहले यह 10 से अधिक निष्पादन के साथ सामना करने में सक्षम नहीं था, आउटपुट विशेष रूप से उपयोगी नहीं था, और प्रलेखन भयानक है।
मैट जॉइनर

1
@ ओथोफाइल: एआरएम, पावर, ia64, ...
एनिकॉर्न



हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.