2012-06-16 17 views
16

मैं अपने सी ++ कोड के रनटाइम को मापना चाहता हूं। मेरे कोड को निष्पादित करने में लगभग 12 घंटे लगते हैं और मैं इस समय अपने कोड के निष्पादन के अंत में लिखना चाहता हूं। मैं अपने कोड में यह कैसे कर सकता हूं?सी ++ कोड के रनटाइम को मापना?

ऑपरेटिंग सिस्टम Linux

+1

आप किस ऑपरेटिंग सिस्टम पर अपने कोड चल रहे हैं? –

+0

मुझे एक साथ कई कोड प्रोफाइल करना पसंद है। – Puppy

+1

जब भी आप प्रोग्राम शुरू करते हैं तो बस 'time' कमांड का उपयोग करें। – Jasen

उत्तर

7

मैं अपनी परियोजनाओं में से एक में कुछ इस तरह का प्रयोग किया:

#include <sys/time.h> 

struct timeval start, end; 
gettimeofday(&start, NULL); 
//Compute 
gettimeofday(&end, NULL); 
double elapsed = ((end.tv_sec - start.tv_sec) * 1000) 
     + (end.tv_usec/1000 - start.tv_usec/1000); 

यह मिलीसेकंड के लिए है और यह दोनों C और C++ के लिए काम करता है।

auto start = std::chrono::system_clock::now(); 

/* do some work */ 

auto end = std::chrono::system_clock::now(); 
auto elapsed = end - start; 
std::cout << elapsed.count() << '\n'; 

तुम भी विवरण के स्तर को निर्दिष्ट कर सकते हैं एक अवधि का प्रतिनिधित्व करने के लिए उपयोग करने के लिए:

54

आप सी ++ 11 उपयोग कर रहे हैं आप system_clock::now() उपयोग कर सकते हैं

// this constructs a duration object using milliseconds 
auto elapsed = 
    std::chrono::duration_cast<std::chrono::milliseconds>(end - start); 

// this constructs a duration object using seconds 
auto elapsed = 
    std::chrono::duration_cast<std::chrono::seconds>(end - start); 

आप उपयोग नहीं कर सकते सी + +11, फिर बूस्ट से chrono पर एक नज़र डालें।

ऐसे मानक पुस्तकालयों का उपयोग करने के बारे में सबसे अच्छी बात यह है कि उनकी पोर्टेबिलिटी वास्तव में उच्च है (उदाहरण के लिए, वे दोनों लिनक्स और विंडोज में काम करते हैं)। इसलिए यदि आप बाद में अपना आवेदन बंद करने का निर्णय लेते हैं तो आपको बहुत ज्यादा चिंता करने की आवश्यकता नहीं है।

सी-जैसे दृष्टिकोणों के विपरीत ये पुस्तकालय एक आधुनिक सी ++ डिज़ाइन का भी पालन करते हैं।

संपादित करें: उपरोक्त उदाहरण wall-clock time को मापने के लिए उपयोग किया जा सकता है। हालांकि, यह एक कार्यक्रम के निष्पादन समय को मापने का एकमात्र तरीका नहीं है। सबसे पहले, हम उपयोगकर्ता और सिस्टम समय के बीच अलग कर सकते हैं:

  • उपयोगकर्ता समय: समय user space में चल रहे इस कार्यक्रम के द्वारा खर्च किए।
  • सिस्टम समय: सिस्टम (या कर्नेल) स्थान में चल रहे प्रोग्राम द्वारा बिताए गए समय। उदाहरण के लिए एक प्रोग्राम कर्नेल स्पेस में प्रवेश करता है जब system call निष्पादित करता है।

किसी भी कार्यक्रम के निष्पादन समय के हिस्से के रूप में सिस्टम के समय पर विचार करना आवश्यक है या नहीं। उदाहरण के लिए, यदि उद्देश्य उपयोगकर्ता कोड पर एक कंपाइलर अनुकूलन को मापना है तो सिस्टम सिस्टम को छोड़ना शायद बेहतर है। दूसरी ओर, यदि उपयोगकर्ता यह निर्धारित करना चाहता है कि सिस्टम कॉल एक महत्वपूर्ण ओवरहेड हैं, तो सिस्टम समय को मापना भी आवश्यक है।

इसके अलावा, चूंकि अधिकांश आधुनिक सिस्टम time-shared हैं, विभिन्न प्रोग्राम कई कंप्यूटिंग संसाधनों (उदाहरण के लिए, सीपीयू) के लिए प्रतिस्पर्धा कर सकते हैं। इस तरह के एक मामले में, एक और भेद किया जा सकता है:

  • Wall-clock time: दीवार-घड़ी समय कार्यक्रम के निष्पादन उसी तरह से मापा जाता है, के रूप में अगर हम एक बाहरी (दीवार) घड़ी का उपयोग कर रहे थे का उपयोग करके। यह दृष्टिकोण कार्यक्रमों के बीच बातचीत पर विचार नहीं करता है।
  • CPU time: इस मामले में हम केवल समय है कि एक कार्यक्रम वास्तव में सीपीयू पर चल रहा है गिनती।यदि कोई प्रोग्राम (पी 1) किसी अन्य (पी 2) के साथ सह-निर्धारित होता है, और हम पी 1 के लिए सीपीयू का समय प्राप्त करना चाहते हैं, तो इस दृष्टिकोण में समय शामिल नहीं है जबकि पी 2 चल रहा है और पी 1 सीपीयू के लिए इंतजार कर रहा है (जैसा कि विपरीत है दीवार घड़ी समय दृष्टिकोण)।

CPU समय को मापने के लिए, बूस्ट एक set of extra clocks में शामिल हैं:

  • process_real_cpu_clock, कब्जा दीवार घड़ी CPU समय वर्तमान प्रक्रिया द्वारा खर्च।
  • process_user_cpu_clock, वर्तमान प्रक्रिया द्वारा खर्च किए गए उपयोगकर्ता-सीपीयू समय को कैप्चर करता है।
  • process_system_cpu_clock, वर्तमान प्रक्रिया द्वारा खर्च किए गए सिस्टम-सीपीयू समय को कैप्चर करता है। एक tuple-like class process_cpu_clock, जो वास्तविक, उपयोगकर्ता-सीपीयू, और सिस्टम-सीपीयू प्रक्रिया समय को एक साथ कैप्चर करता है।
  • thread_clock थ्रेड स्थिर घड़ी वर्तमान धागे (जब प्लेटफार्म द्वारा समर्थित) द्वारा बिताए गए समय को दे रही है।

दुर्भाग्यवश, सी ++ 11 में ऐसे घड़ियों नहीं हैं। लेकिन बूस्ट एक व्यापक रूप से उपयोग की जाने वाली लाइब्रेरी है और, शायद, इन अतिरिक्त घड़ियों को किसी बिंदु पर सी ++ 1x में शामिल किया जाएगा। इसलिए, यदि आप बूस्ट का उपयोग करते हैं तो आप तैयार होंगे जब नया सी ++ मानक उन्हें जोड़ता है।

अंत में, यदि आप कमांड लाइन से निष्पादित करने के लिए एक प्रोग्राम लेते हैं (जैसा कि आपके प्रोग्राम में कुछ कोड जोड़ने के विपरीत है), तो आप time कमांड पर देख सकते हैं, जैसा कि @ BЈовић सुझाता है। हालांकि, यह दृष्टिकोण आपको अपने प्रोग्राम के अलग-अलग हिस्सों को मापने नहीं देगा (उदाहरण के लिए, फ़ंक्शन निष्पादित करने में लगने वाला समय)।

+0

मेरी सवाल यह है: कैसे सी ++/C++ 11 मतभेद और बढ़ावा देने-पुस्तकालयों के बारे में? – gaussblurinc

+1

@loldop मुझे विश्वास है कि सी ++ 11 कार्यान्वयन बूस्ट क्रोनो लाइब्रेरी का सबसेट है। तो उनके पास एक बहुत ही समान एपीआई होना चाहिए (अगर ऐसा नहीं है)। सी ++ 11 का उपयोग करने का लाभ यह है कि आपको बूस्ट का उपयोग करने की आवश्यकता नहीं है (यदि क्रोनो बूस्ट से एकमात्र लाइब्रेरी है)। – betabandido

10

आप अपने प्रोग्राम को शुरू करने के लिए time का उपयोग कर सकते हैं। जब यह समाप्त होता है, तो यह कार्यक्रम चलाने के बारे में अच्छा समय आंकड़े प्रिंट करता है। मुद्रित करना कॉन्फ़िगर करना आसान है। डिफ़ॉल्ट रूप से, यह प्रोग्राम निष्पादित करने के लिए उपयोगकर्ता और सीपीयू बार मुद्रित करता है।

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

* गलत मान, मैं मतलब यह समय यह कार्यक्रम पर अमल करने लग गए पाने के लिए आसान है, लेकिन उस समय प्रोग्राम निष्पादन के दौरान सीपीयू लोड पर निर्भर करता है। अपेक्षाकृत स्थिर समय माप प्राप्त करने के लिए, यह CPU लोड पर निर्भर नहीं है, कोई time का उपयोग करके एप्लिकेशन को निष्पादित कर सकता है और सीपीयू का माप परिणाम के रूप में उपयोग कर सकता है।

+1

मुझे लगता है कि अवरोध भी उस कार्यक्रम का हिस्सा है जब यह प्रोग्राम चलाने के लिए लेता है, नहीं? –

+1

@EitanT नहीं, क्योंकि CPU (ओं) लोड में परिवर्तन होता है। वर्तमान भार को 1 घंटे या कल में लोड के समान नहीं होना चाहिए। –

+0

अब मैं देखता हूं कि आपका क्या मतलब है। –

16

std::chrono::steady_clock का उपयोग करें और std::chrono::system_clock का उपयोग C++ 11 में रन टाइम को मापने के लिए नहीं करें। कारण (के हवाले से system_clock के प्रलेखन) है:

सबसे सिस्टम पर

, सिस्टम का समय किसी भी क्षण में समायोजित किया जा सकता

जबकि steady_clock monotonic है और बेहतर मापने अंतराल के लिए अनुकूल है:

कक्षा std :: chrono :: steady_clock एक monotonic घड़ी का प्रतिनिधित्व करता है। इस घड़ी के अंक कम नहीं हो सकते हैं क्योंकि भौतिक समय आगे बढ़ता है। यह घड़ी दीवार घड़ी के समय से संबंधित नहीं है, और मापने के अंतराल के लिए सबसे उपयुक्त है।

auto start = std::chrono::steady_clock::now(); 
// do something 
auto finish = std::chrono::steady_clock::now(); 
double elapsed_seconds = std::chrono::duration_cast< 
    std::chrono::duration<double> >(finish - start).count(); 

एक छोटा सा व्यावहारिक टिप:

यहाँ एक उदाहरण है अगर तुम रन टाइम मापने और सेकंड std::chrono::duration_cast<std::chrono::seconds> रिपोर्ट करना चाहते हैं कर रहे हैं कि तुम क्या जरूरत है क्योंकि यह आपको पूरे सेकंड की संख्या देता है शायद ही कभी होता है। double के रूप में सेकेंड में समय प्राप्त करने के लिए ऊपर दिए गए उदाहरण का उपयोग करें।

+0

मुझे व्यावहारिक युक्ति नहीं मिली। 'Std :: chrono :: duration_cast 'कुल सेकंड के रूप में दो समय बिंदुओं के बीच अंतर प्राप्त करने का तरीका नहीं है? – Isaac

+0

@Isaac क्या मेरा मतलब है कि 'std :: chrono :: duration_cast ' 0 वापस आ जाएगी अगर अंतर एक सेकंड से भी कम है। यदि आप एक फ्लोटिंग-पॉइंट नंबर के रूप में अवधि चाहते हैं तो 'सेकंड' के बजाय 'डबल' का उपयोग करें। – vitaut

0

तुम भी कुछ टाइमर क्लासेस शुरू कोशिश करते हैं और स्वचालित रूप से बंद करो, और औसत, अधिकतम और न्यूनतम समय कोड के किसी भी ब्लॉक, साथ ही कॉल की संख्या में खर्च पर आंकड़े एकत्र कर सकता है। ये CXX-rtimer कक्षाएं GitHub पर उपलब्ध हैं, और) std :: Chrono, clock_gettime (प्रयोग करने के लिए सहायता प्रदान करते हैं, या बढ़ावा देने :: posix_time एक बैक-एंड घड़ी स्रोत के रूप में। कार्यक्रम पूरा होने पर एसटीडी लिखा आँकड़े :: cerr समय के साथ

void timeCriticalFunction() { 
    static rtimers::cxx11::DefaultTimer timer("expensive"); 
    auto scopedStartStop = timer.scopedStart(); 
    // Do something costly... 
} 

:

इन टाइमर के साथ, आप की तरह कुछ कर सकते हैं।

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