c++ सी++ में किसी फ़ंक्शन के निष्पादन समय को मापना




optimization profiling (4)

मैं यह जानना चाहता हूं कि लिनक्स पर निष्पादित करने के लिए मेरे सी ++ प्रोग्राम में एक निश्चित फ़ंक्शन कितना समय लगता है। बाद में, मैं एक गति तुलना करना चाहता हूँ। मैंने कई बार फ़ंक्शन देखा लेकिन बढ़ावा से इसे समाप्त कर दिया। Chrono:

process_user_cpu_clock, captures user-CPU time spent by the current process

अब, मैं स्पष्ट नहीं हूं कि अगर मैं उपर्युक्त फ़ंक्शन का उपयोग करता हूं, तो क्या मुझे एकमात्र समय मिलेगा जो सीपीयू ने उस फ़ंक्शन पर खर्च किया था?

दूसरा, मुझे उपरोक्त फ़ंक्शन का उपयोग करने का कोई उदाहरण नहीं मिला। क्या कोई मेरी मदद कर सकता है कि उपरोक्त फ़ंक्शन का उपयोग कैसे करें?

पीएस: अभी, मैं सेकंड में समय प्राप्त करने के लिए std::chrono::system_clock::now() का उपयोग कर रहा हूं लेकिन यह हर बार विभिन्न CPU लोड के कारण मुझे अलग-अलग परिणाम देता है।


यहां एक ऐसा फ़ंक्शन है जो तर्क के रूप में पारित किसी भी फ़ंक्शन के निष्पादन समय को माप देगा:

#include <chrono>
#include <utility>

typedef std::chrono::high_resolution_clock::time_point TimeVar;

#define duration(a) std::chrono::duration_cast<std::chrono::nanoseconds>(a).count()
#define timeNow() std::chrono::high_resolution_clock::now()

template<typename F, typename... Args>
double funcTime(F func, Args&&... args){
    TimeVar t1=timeNow();
    func(std::forward<Args>(args)...);
    return duration(timeNow()-t1);
}

उदाहरण का उपयोग:

#include <iostream>
#include <algorithm>

typedef std::string String;

//first test function doing something
int countCharInString(String s, char delim){
    int count=0;
    String::size_type pos = s.find_first_of(delim);
    while ((pos = s.find_first_of(delim, pos)) != String::npos){
        count++;pos++;
    }
    return count;
}

//second test function doing the same thing in different way
int countWithAlgorithm(String s, char delim){
    return std::count(s.begin(),s.end(),delim);
}


int main(){
    std::cout<<"norm: "<<funcTime(countCharInString,"precision=10",'=')<<"\n";
    std::cout<<"algo: "<<funcTime(countWithAlgorithm,"precision=10",'=');
    return 0;
}

आउटपुट:

norm: 15555
algo: 2976

एक समारोह निष्पादन समय खोजने के लिए सरल कार्यक्रम।

#include <iostream>
#include <ctime> // time_t
#include <cstdio>

void function()
{
     for(long int i=0;i<1000000000;i++)
     {
        // do nothing
     }
}

int main()
{

time_t begin,end; // time_t is a datatype to store time values.

time (&begin); // note time before execution
function();
time (&end); // note time after execution

double difference = difftime (end,begin);
printf ("time taken for function() %.2lf seconds.\n", difference );

return 0;
}

यह C ++ 11 में उपयोग करने में बहुत आसान तरीका है। आपको <chrono> शीर्षलेख से std::chrono::high_resolution_clock का उपयोग करना होगा।

इसे इस तरह प्रयोग करें:

#include <iostream>
#include <chrono>

using namespace std;
using namespace std::chrono;

void function()
{
    long long number = 0;

    for( long long i = 0; i != 2000000; ++i )
    {
       number += 5;
    }
}

int main()
{
    high_resolution_clock::time_point t1 = high_resolution_clock::now();
    function();
    high_resolution_clock::time_point t2 = high_resolution_clock::now();

    auto duration = duration_cast<microseconds>( t2 - t1 ).count();

    cout << duration;
    return 0;
}

यह समारोह की अवधि को माप देगा।

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


फ़ंक्शन या किसी भी कोड ब्लॉक के विलुप्त समय को मापने के लिए यहां एक उत्कृष्ट शीर्षलेख केवल क्लास टेम्पलेट है:

#ifndef EXECUTION_TIMER_H
#define EXECUTION_TIMER_H

template<class Resolution = std::chrono::milliseconds>
class ExecutionTimer {
public:
    using Clock = std::conditional_t<std::chrono::high_resolution_clock::is_steady,
                                     std::chrono::high_resolution_clock,
                                     std::chrono::steady_clock>;
private:
    const Clock::time_point mStart = Clock::now();

public:
    ExecutionTimer() = default;
    ~ExecutionTimer() {
        const auto end = Clock::now();
        std::ostringstream strStream;
        strStream << "Destructor Elapsed: "
                  << std::chrono::duration_cast<Resolution>( end - mStart ).count()
                  << std::endl;
        std::cout << strStream.str() << std::endl;
    }    

    inline void stop() {
        const auto end = Clock::now();
        std::ostringstream strStream;
        strStream << "Stop Elapsed: "
                  << std::chrono::duration_cast<Resolution>(end - mStart).count()
                  << std::endl;
        std::cout << strStream.str() << std::endl;
    }

}; // ExecutionTimer

#endif // EXECUTION_TIMER_H

यहां कुछ उपयोग दिए गए हैं:

int main() {
    { // empty scope to display ExecutionTimer's destructor's message
         // displayed in milliseconds
         ExecutionTimer<std::chrono::milliseconds> timer;

         // function or code block here

         timer.stop();

    } 

    { // same as above
        ExecutionTimer<std::chrono::microseconds> timer;

        // code block here...

        timer.stop();
    }

    {  // same as above
       ExecutionTimer<std::chrono::nanoseconds> timer;

       // code block here...

       timer.stop();

    }

    {  // same as above
       ExecutionTimer<std::chrono::seconds> timer;

       // code block here...

       timer.stop();

    }              

    return 0;
}

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





profiling