सी

2016-10-08 7 views
7

में घड़ी() फ़ंक्शन की शुद्धता मेरे पास कुछ कोड है जो कोड ब्लॉक के निष्पादन समय को निर्धारित करने का प्रयास करता है।सी

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

int main() 
{ 
    clock_t start_t, end_t, total_t; 
    int i; 

    start_t = clock(); //clock start 
    printf("Starting of the program, start_t = %ld\n", start_t); 

    printf("Going to scan a big loop, start_t = %ld\n", start_t); 
    for(i=0; i< 10000000; i++) //trying to determine execution time of this block 
    { 
    } 
    end_t = clock(); //clock stopped 
    printf("End of the big loop, end_t = %ld\n", end_t); 

    total_t = (long int)(end_t - start_t); 
    printf("Total time taken by CPU: %lu\n", total_t ); 

    return(0); 
} 

मेरी मशीन पर कोड स्निपेट के उत्पादन

Starting of the program, start_t = 8965 
Going to scan a big loop, start_t = 8965 
End of the big loop, end_t = 27259 
Total time taken by CPU: 18294 

तो है अगर मेरी सीपीयू 21 मेगाहर्ट्ज पर चल रहा था और यह सोचते हैं कि यह केवल एक चीज निष्पादित हो रही थी, प्रत्येक मशीन चक्र लगभग होगा 47 नैनोसेकंड के बराबर (18294 * 47) = 85 9 818 नैनोसेकंड।

क्या यह मेरे कोड में लूप के लिए निष्पादन का समय होगा? क्या मैं यहां कुछ गलत धारणाएं कर रहा हूं।

+0

सेकंड में समय प्राप्त करने के लिए आपको संख्या को विभाजित करना चाहिए, उदाहरण के लिए 'CLOCKS_PER_SEC' के साथ, आपके मामले में' total_t'। ध्यान दें कि आपको काम करने के लिए 'flo_t' को फ़्लोटिंग पॉइंट मान में डालना होगा। –

+1

आपकी नामकरण योजना पर भी एक छोटा सा नाइटपिकिंग: प्रत्यय '_t' के साथ समाप्त होने वाले प्रतीक आमतौर पर टाइप-उपनाम (जैसे 'टाइपडेफ़' के साथ बनाए गए) के लिए उपयोग किए जाते हैं। उदाहरण के लिए 'size_t' या 'time_t' और यहां तक ​​कि' clock_t'। –

+0

@ जोचिमपिलबोर्ग मैंने घड़ी() फ़ंक्शन के लिए प्रलेखन की समीक्षा की और CLOCK_PER_SEC एक सेकंड के 1/100 वें तक सटीक समय लौटाएगा और मैं 10 माइक्रोसॉन्ड तक संकल्प की तलाश कर रहा हूं इसलिए मैंने उल्लिखित दृष्टिकोण का उपयोग किया। इसके अलावा, मैं इसे विभिन्न प्लेटफॉर्म और आर्किटेक्चर पर काम करना चाहता हूं, इसलिए मैंने सोचा कि केवल अंतर की गणना करना और फिर घड़ी की गति के साथ गुणा करना बेहतर विकल्प होगा क्योंकि CLOCKS_PER_SEC आर्किटेक्चर के साथ बदल जाएगा। – user2808264

उत्तर

4

clock फ़ंक्शन द्वारा उपयोग किए जाने वाले समय की इकाई मनमानी है। अधिकांश प्लेटफ़ॉर्म पर, यह प्रोसेसर की गति से असंबंधित नहीं है। यह बाहरी टाइमर इंटरप्ट की आवृत्ति से अधिक सामान्य रूप से संबंधित होता है - जिसे सॉफ़्टवेयर में कॉन्फ़िगर किया जा सकता है - या एक ऐतिहासिक मूल्य जिसे प्रोसेसर विकास के वर्षों के माध्यम से संगतता के लिए रखा गया है। वास्तविक समय में कनवर्ट करने के लिए आपको मैक्रो CLOCKS_PER_SEC का उपयोग करने की आवश्यकता है।

printf("Total time taken by CPU: %fs\n", (double)total_t/CLOCKS_PER_SEC); 

सी मानक पुस्तकालय हार्डवेयर की एक विस्तृत श्रृंखला पर कार्यान्वयन योग्य होने के लिए डिजाइन किया गया था, प्रोसेसर है कि एक आंतरिक घड़ी की जरूरत नहीं है और एक बाहरी परिधीय पर भरोसा समय बताने के लिए भी शामिल है। कई प्लेटफार्मों में time की तुलना में दीवार घड़ी के समय को मापने के लिए और सटीक तरीके हैं और clock से CPU खपत को मापने के लिए अधिक सटीक तरीके हैं। उदाहरण के लिए, POSIX सिस्टम (उदा। लिनक्स और अन्य यूनिक्स-जैसी प्रणालियों) पर, आप getrusage का उपयोग कर सकते हैं, जिसमें माइक्रोसॉन्ड परिशुद्धता है।

struct timeval start, end; 
struct rusage usage; 
getrusage(RUSAGE_SELF, &usage); 
start = usage.ru_utime; 
… 
getrusage(RUSAGE_SELF, &usage); 
end = usage.ru_utime; 
printf("Total time taken by CPU: %fs\n", (double)(end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec)/1e-6); 

जहां उपलब्ध हो, clock_gettime(CLOCK_THREAD_CPUTIME_ID) या clock_gettime(CLOCK_PROCESS_CPUTIME_ID) बेहतर परिशुद्धता दे सकता है। इसमें नैनोसेकंद परिशुद्धता है।

सटीकता और सटीकता के बीच अंतर नोट करें: सटीक वह इकाई है जो मूल्यों की सूचना दी जाती है। शुद्धता यह है कि रिपोर्ट किए गए मान वास्तविक मूल्यों के करीब कितने करीब हैं। जब तक आप real-time system पर काम नहीं कर रहे हैं, तब तक कोई कठोर गारंटी नहीं है कि कोड का एक टुकड़ा कितना समय लेता है, जिसमें माप कार्यों का आविष्कार भी शामिल है।

कुछ प्रोसेसर में चक्र घड़ियों हैं जो दीवार घड़ी के समय प्रोसेसर चक्रों की गणना करते हैं, लेकिन यह बहुत सिस्टम-विशिष्ट हो जाता है।

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

+0

@Giles यह वही है जो मुझे चाहिए था। घड़ी के कार्य की तुलना में इसमें 1 तक का संकल्प है जिसमें 100 एमएस का संकल्प था। लेकिन क्या आप जानते हैं कि यह कोड पोर्टेबल है या नहीं। मुझे एआरएम एम 0 सिस्टम पर चलाने की जरूरत है। क्या कोई तरीका है कि मैं इस कोड को पोर्टेबल बना सकता हूं? – user2808264

+0

@ user2808264 अगर आपको 'घड़ी' से परे कुछ चाहिए तो यह पोर्टेबल नहीं होगा, आप या तो ऑपरेटिंग सिस्टम या सीपीयू या दोनों पर निर्भरता बनाएंगे। जांचें कि आपका ओएस क्या प्रदान करता है। यदि आप नंगे धातु पर चल रहे हैं, यदि आप 1μs सटीकता के करीब चाहते हैं तो आपको चक्र-सटीक काउंटर की आवश्यकता होगी, जांचें कि आपके सीपीयू पर कौन सी डिबगिंग कार्यक्षमता मौजूद है (मुझे लगता है कि यह एक वैकल्पिक सुविधा है)। यदि आपको उस सटीकता की आवश्यकता नहीं है तो आप [सिस्टिक टाइमर] (http://sushihangover.github.io/cortex-m-systick-polling-vs-interrupts/) का उपयोग कर सकते हैं जो वैकल्पिक लेकिन व्यापक है। – Gilles