समय (1) के आउटपुट में 'वास्तविक', 'उपयोगकर्ता' और 'sys' का क्या अर्थ है?


1745
$ time foo
real        0m0.003s
user        0m0.000s
sys         0m0.004s
$

समय के आउटपुट में 'वास्तविक', 'उपयोगकर्ता' और 'एसईएस' का क्या मतलब है?

मेरे ऐप को बेंचमार्क करते समय कौन सा सार्थक है?


2
मैं उनमें से केवल एक पर कैसे पहुंच सकता हूं? उदाहरण के लिए सिर्फ वास्तविक समय?
Mojtaba अहमदी

1
@ConcernedOfTunbridgeWells
Mojtaba Ahmadi


7
यदि आपका कार्यक्रम उस तेजी से निकलता है, तो उनमें से कोई भी सार्थक नहीं है, यह सब सिर्फ स्टार्टअप ओवरहेड है। यदि आप पूरे कार्यक्रम को मापना चाहते हैं time, तो ऐसा कुछ करें जो कम से कम एक सेकंड ले।
पीटर कॉर्डेस

5
यह नोट करना वास्तव में महत्वपूर्ण है कि timeबैश कीवर्ड है। तो टाइपिंग man timeहै नहीं आप बैश के लिए एक आदमी पेज दे रही है time, बल्कि इसके लिए आदमी पेज दे रहा है /usr/bin/time। इसने मुझे उलझा दिया है।
चिड़चिड़ा_फीड_स्कैंडरोम

जवाबों:


2059

वास्तविक, उपयोगकर्ता और Sys प्रक्रिया समय आँकड़े

इनमें कुछ चीजें एक जैसी नहीं हैं। वास्तविक वास्तविक बीता हुआ समय संदर्भित करता है; उपयोगकर्ता और Sys केवल प्रक्रिया द्वारा उपयोग किए जाने वाले CPU समय का संदर्भ देते हैं।

  • वास्तविक दीवार घड़ी का समय है - कॉल के शुरू से अंत तक का समय। यह सभी बीता हुआ समय है जिसमें अन्य प्रक्रियाओं द्वारा उपयोग किए जाने वाले समय के स्लाइस शामिल हैं और समय अवरुद्ध हो जाता है (उदाहरण के लिए अगर यह I / O के पूरा होने की प्रतीक्षा कर रहा है)।

  • उपयोगकर्ता प्रक्रिया के भीतर उपयोगकर्ता-मोड कोड (कर्नेल के बाहर) में खर्च किए गए सीपीयू समय की मात्रा है। यह केवल वास्तविक सीपीयू समय है जो प्रक्रिया को निष्पादित करने में उपयोग किया जाता है। अन्य प्रक्रियाएं और समय प्रक्रिया अवरुद्ध हो जाती है इस आंकड़े की ओर गिनती नहीं है।

  • Sys प्रक्रिया में कर्नेल में बिताए गए CPU समय की मात्रा है। इसका अर्थ है कि लाइब्रेरी कोड के विपरीत , कर्नेल के भीतर सिस्टम कॉल में बिताए गए CPU समय को निष्पादित करना , जो अभी भी उपयोगकर्ता-स्थान में चल रहा है। 'उपयोगकर्ता' की तरह, यह प्रक्रिया द्वारा उपयोग किया जाने वाला केवल CPU समय है। कर्नेल मोड के संक्षिप्त विवरण के लिए नीचे देखें (जिसे 'पर्यवेक्षक' मोड के रूप में भी जाना जाता है) और सिस्टम कॉल तंत्र।

User+Sysआपको बताएगा कि आपकी प्रक्रिया में वास्तविक सीपीयू समय कितना इस्तेमाल किया गया है। ध्यान दें कि यह सभी सीपीयू के पार है, इसलिए यदि प्रक्रिया में कई थ्रेड्स हैं (और यह प्रक्रिया एक से अधिक प्रोसेसर वाले कंप्यूटर पर चल रही है) तो यह संभावित रूप से रिपोर्ट की गई दीवार घड़ी के समय से अधिक हो सकती है Real(जो आमतौर पर होती है)। ध्यान दें कि उत्पादन में इन आंकड़ों में शामिल हैं Userऔर Sysसभी चाइल्ड प्रक्रियाओं (और उनके वंशज) के समय के साथ-साथ वे एकत्र होने वाले सकता है किया गया है, जैसे द्वारा wait(2)या waitpid(2), हालांकि अंतर्निहित प्रणाली कॉल प्रक्रिया के लिए आँकड़े और उसके बच्चों को अलग से लौट आते हैं।

द्वारा जारी आँकड़ों की उत्पत्ति time (1)

द्वारा timeबताए गए आंकड़े विभिन्न सिस्टम कॉल से एकत्रित किए जाते हैं। 'उपयोगकर्ता' और 'Sys' विशेष प्रणाली के आधार पर wait (2)( POSIX ) या times (2)( POSIX ) से आते हैं । 'रियल' की गणना gettimeofday (2)कॉल से एकत्र किए गए प्रारंभ और अंत समय से की जाती है । सिस्टम के संस्करण के आधार पर, विभिन्न अन्य आंकड़े जैसे कि संदर्भ स्विच की संख्या को भी इकट्ठा किया जा सकता है time

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

कर्नेल बनाम उपयोगकर्ता मोड पर एक संक्षिप्त प्राइमर

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

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

सी लाइब्रेरी में 'सिस्टम' कॉल (विशेष रूप से मैन पेजों की धारा 2 में वर्णित) में एक उपयोगकर्ता-मोड घटक है, जिसे आप वास्तव में अपने सी प्रोग्राम से कॉल करते हैं। पर्दे के पीछे, वे कर्नेल को I / O जैसी विशिष्ट सेवाएं करने के लिए एक या अधिक सिस्टम कॉल जारी कर सकते हैं, लेकिन उनके पास अभी भी उपयोगकर्ता-मोड में चलने वाला कोड है। यदि वांछित है तो किसी भी उपयोगकर्ता अंतरिक्ष कोड से कर्नेल मोड को सीधे जारी करना भी काफी संभव है, हालांकि आपको कॉल के लिए रजिस्टरों को सही ढंग से सेट करने के लिए असेंबली भाषा का एक स्निपेट लिखना पड़ सकता है।

'Sys' के बारे में अधिक

ऐसी चीजें हैं जो आपका कोड उपयोगकर्ता मोड से नहीं कर सकता है - मेमोरी आवंटित करने या हार्डवेयर (एचडीडी, नेटवर्क, आदि) तक पहुंचने जैसी चीजें। ये कर्नेल की देखरेख में हैं, और यह अकेले उन्हें कर सकता है। कुछ ऑपरेशन इन कर्नेल फ़ंक्शंस को पसंद करेंगे mallocया fread/ fwriteकरेंगे और फिर 'sys' समय के रूप में गिना जाएगा। दुर्भाग्य से यह उतना आसान नहीं है जितना "मॉलॉक के लिए हर कॉल 'sys' समय में गिना जाएगा।" कॉल करने mallocका कार्य स्वयं का कुछ प्रसंस्करण करेगा (अभी भी 'उपयोगकर्ता समय' में गिना जाता है) और फिर कहीं-कहीं यह कर्नेल में फ़ंक्शन को भी कह सकता है ('sys' समय में गिना जाता है)। कर्नेल कॉल से लौटने के बाद, 'उपयोगकर्ता' में कुछ और समय होगा और फिरmallocआपके कोड पर वापस आ जाएगा। जैसे कि स्विच कब होता है, और कर्नेल मोड में इसका कितना खर्च होता है ... आप नहीं कह सकते। यह पुस्तकालय के कार्यान्वयन पर निर्भर करता है। इसके अलावा, अन्य प्रतीत होता है निर्दोष कार्यों का भी उपयोग कर सकते हैं mallocऔर पृष्ठभूमि में पसंद है, जो फिर से 'sys' में कुछ समय होगा।


15
क्या बाल प्रक्रियाओं द्वारा खर्च किए गए समय को वास्तविक / sys में गिना जाता है?
रॉन

1
@ron - लिनक्स मैन पेज के अनुसार, यह प्रक्रिया के समय के साथ 'c' समय को एकत्रित करता है, इसलिए मुझे लगता है कि यह करता है। माता-पिता के समय और बच्चे के समय (2) कॉल से अलग-अलग उपलब्ध हैं, हालांकि। मुझे लगता है कि समय का सोलारिस / SysV संस्करण (1) कुछ ऐसा ही करता है।
कंसर्नडऑफटुनब्रिजवेल्स 10

3
उपयोगकर्ता + Sys आपको एक प्रक्रिया के CPU उपयोग को मापने की सुविधा देता है। आप इसे बेंचमार्क प्रदर्शन के लिए उपयोग कर सकते हैं। यह बहु-थ्रेडेड कोड के लिए विशेष रूप से उपयोगी है जहां एक से अधिक सीपीयू कोर एक संगणना पर काम कर सकते हैं।
ConcernedOfTunbridgeWells

1
विषय पर ठीक नहीं है, फिर भी: "\ time <cmd>" चलाना दिलचस्प है - यह अधिक विवरण प्रदान करता है: (टिप्पणी में खराब प्रारूपण): $ समय ps PID TTY TIME CMD 9437 pts / 19 00:00:00 vash 11459 pts / 19 00:00:00 ps वास्तविक 0m0.025s उपयोगकर्ता 0m0.004s sys 0m0.018s $ \ time ps PID TTY TIME CMD 9437 pts / 19 00:00:00 bash 11461 अंक / 19 00:00:00 समय 11462 pts / 19 00:00:00 ps 0.00user 0.01system 0: 00.02elapsed 95% CPU (0avgtext + 0avgdata 2160maxresident) k 0inputs + 0outputs (0mat + 103minor) पेजफॉल्ट्स 0swaps $
kaiwan

1
(प्रचलित टिप्पणी में वर्ण से बाहर भाग गया): अधिक विस्तार से? Perf [1], [२] का प्रयोग करें। [1] perf.wiki.kernel.org/index.php/Main_Page [2] brendangregg.com/perf.html
kaiwan

285

पर विस्तार करने के लिए स्वीकार किए जाते हैं जवाब , मैं सिर्फ एक और कारण है कि उपलब्ध कराना चाहते थे realuser+ sys

ध्यान रखें कि रखें real, वास्तविक बीता हुआ समय का प्रतिनिधित्व करता है, जबकि userऔर sysमूल्यों सीपीयू निष्पादन समय प्रतिनिधित्व करते हैं। नतीजतन, एक मल्टीकोर सिस्टम पर, userऔर / या sysसमय (साथ ही उनकी राशि) वास्तव में वास्तविक समय से अधिक हो सकता है । उदाहरण के लिए, एक जावा ऐप पर मैं क्लास के लिए दौड़ रहा हूं मुझे यह मान मिलता है:

real    1m47.363s
user    2m41.318s
sys     0m4.013s

11
मैं हमेशा इस बारे में सोचता था। चूंकि मुझे पता है कि मेरे प्रोग्राम सिंगल थ्रेडेड हैं, इसलिए उपयोगकर्ता और वास्तविक समय के बीच का अंतर VM ओवरहेड, सही होना चाहिए?
क्वांटम 7

9
जरुरी नहीं; सोलारिस मशीनों पर सन जेवीएम और साथ ही मैक ओएस एक्स पर ऐप्पल का जेवीएम सिंगल-थ्रेडेड ऐप्स में एक से अधिक कोर का उपयोग करने का प्रबंधन करता है। यदि आप एक जावा प्रक्रिया का एक नमूना करते हैं, तो आप देखेंगे कि कचरा संग्रह जैसी चीजें अलग-अलग धागे पर चलती हैं (और कुछ अन्य सामान भी जो मुझे अपने सिर के ऊपर से याद नहीं हैं)। मैं नहीं जानता कि क्या आप वास्तव में उस "वीएम ओवरहेड" को समाप्त करना चाहते हैं।
लेंसोवेट

4
मुझे लगता है कि अप-वोटों की मात्रा ने आपको अब काफी प्रतिष्ठा दी है: डी। तो क्या आप के बारे में सोचते हैं realसे अधिक userऔर sysकुल? ओएस ओवरहेड जैसे थ्रेड संदर्भ स्विचिंग हो सकता है?
मुहम्मद गेल्बाना

19
एक अन्य संभावित मुद्दा I / O हो सकता है: यदि आपका एप्लिकेशन किसी फ़ाइल या स्ट्रीम को प्राप्त करने के लिए प्रतीक्षा करने में अच्छा समय व्यतीत करता है, तो जाहिर है कि उपयोगकर्ता / sys समय से वास्तविक समय बहुत अधिक हो जाएगा क्योंकि एक्सेस पाने के लिए प्रतीक्षा करते समय कोई CPU समय का उपयोग नहीं किया जाता है एक फ़ाइल या कुछ इसी तरह के लिए।
लेंसोवेट

1
@MuhammadGelbana - यदि एप्लिकेशन किसी भी कारण से निष्पादित करने से अवरुद्ध है, तो ऐसा हो सकता है। उदाहरण के लिए, यदि यह I / O, IPC या सॉकेट कनेक्शन पर प्रतीक्षा कर रहा है, तो यह बेकार हो जाएगा, जब तक कि ब्लॉकिंग कॉल रिटर्न न हो, तब तक कोई सीपीयू समय जमा नहीं होगा।
कंसर्नडऑफटुनब्रिजवल्स

41

वास्तविक : प्रक्रिया को शुरू से अंत तक चलाने में बिताया गया वास्तविक समय, जैसे कि यह एक स्टॉपवॉच वाले मानव द्वारा मापा गया था

उपयोगकर्ता : गणना के दौरान सभी सीपीयू द्वारा खर्च किए गए संचयी समय

sys : सिस्टम से संबंधित कार्यों जैसे मेमोरी आवंटन के दौरान सभी सीपीयू द्वारा खर्च किया जाने वाला संचयी समय।

ध्यान दें कि कभी-कभी उपयोगकर्ता + sys वास्तविक से अधिक हो सकते हैं, क्योंकि कई प्रोसेसर समानांतर में काम कर सकते हैं।


sysसीपीयू-टाइम को सिस्टम कॉल (और पेज-फॉल्ट हैंडलर?) में खर्च किया जाता है
पीटर कॉर्ड्स

1
realअक्सर "दीवार-घड़ी" समय के रूप में वर्णित है।
पीटर कॉर्ड्स

30

न्यूनतम रन योग्य POSIX C उदाहरण

चीजों को और अधिक ठोस बनाने के लिए, मैं timeकुछ न्यूनतम सी परीक्षण कार्यक्रमों के साथ कुछ चरम मामलों को उदाहरण देना चाहता हूं ।

सभी कार्यक्रमों को संकलित किया जा सकता है और उनके साथ चलाया जा सकता है:

gcc -ggdb3 -o main.out -pthread -std=c99 -pedantic-errors -Wall -Wextra main.c
time ./main.out

और Ubuntu 18.10, GCC 8.2.0, glibc 2.28, लिनक्स कर्नेल 4.18, थिंकपैड P51 लैपटॉप, इंटेल कोर i7-7820HQ CPU (4 कोर / 8 धागे), 2x सैमसंग M471.2K43BB1-CRC RAM (2x 16GiB) में परीक्षण किया गया है।

नींद

गैर-व्यस्त नींद की userया तो गिनती ही नहीं sysहोती है real

उदाहरण के लिए, एक कार्यक्रम जो एक दूसरे के लिए सोता है:

#define _XOPEN_SOURCE 700
#include <stdlib.h>
#include <unistd.h>

int main(void) {
    sleep(1);
    return EXIT_SUCCESS;
}

गिटहब ऊपर

आउटपुट कुछ इस तरह है:

real    0m1.003s
user    0m0.001s
sys     0m0.003s

उपलब्ध होने वाले IO पर अवरुद्ध कार्यक्रमों के लिए भी यही स्थिति है।

उदाहरण के लिए, निम्न प्रोग्राम उपयोगकर्ता को एक चरित्र दर्ज करने और एंटर प्रेस करने के लिए इंतजार करता है:

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

int main(void) {
    printf("%c\n", getchar());
    return EXIT_SUCCESS;
}

गिटहब ऊपर

और यदि आप लगभग एक सेकंड का इंतजार करते हैं, तो यह नींद के उदाहरण की तरह ही आउटपुट करता है:

real    0m1.003s
user    0m0.001s
sys     0m0.003s

इस कारण timeसे आप सीपीयू और आईओ बाध्य कार्यक्रमों के बीच अंतर करने में मदद कर सकते हैं: "सीपीयू बाध्य" और "आई / ओ बाध्य" शब्द का क्या अर्थ है?

कई सूत्र

निम्न उदाहरण थ्रेड nitersपर बेकार शुद्ध सीपीयू-बाउंड कार्य का पुनरावृत्तियों करता है nthreads:

#define _XOPEN_SOURCE 700
#include <assert.h>
#include <inttypes.h>
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

uint64_t niters;

void* my_thread(void *arg) {
    uint64_t *argument, i, result;
    argument = (uint64_t *)arg;
    result = *argument;
    for (i = 0; i < niters; ++i) {
        result = (result * result) - (3 * result) + 1;
    }
    *argument = result;
    return NULL;
}

int main(int argc, char **argv) {
    size_t nthreads;
    pthread_t *threads;
    uint64_t rc, i, *thread_args;

    /* CLI args. */
    if (argc > 1) {
        niters = strtoll(argv[1], NULL, 0);
    } else {
        niters = 1000000000;
    }
    if (argc > 2) {
        nthreads = strtoll(argv[2], NULL, 0);
    } else {
        nthreads = 1;
    }
    threads = malloc(nthreads * sizeof(*threads));
    thread_args = malloc(nthreads * sizeof(*thread_args));

    /* Create all threads */
    for (i = 0; i < nthreads; ++i) {
        thread_args[i] = i;
        rc = pthread_create(
            &threads[i],
            NULL,
            my_thread,
            (void*)&thread_args[i]
        );
        assert(rc == 0);
    }

    /* Wait for all threads to complete */
    for (i = 0; i < nthreads; ++i) {
        rc = pthread_join(threads[i], NULL);
        assert(rc == 0);
        printf("%" PRIu64 " %" PRIu64 "\n", i, thread_args[i]);
    }

    free(threads);
    free(thread_args);
    return EXIT_SUCCESS;
}

GitHub अपस्ट्रीम + प्लॉट कोड

फिर हम अपने 8 हाइपरथ्रेड सीपीयू पर एक निश्चित 10 ^ 10 पुनरावृत्तियों के लिए थ्रेड्स की संख्या के एक फ़ंक्शन के रूप में दीवार, उपयोगकर्ता और sys प्लॉट करते हैं:

यहां छवि विवरण दर्ज करें

प्लॉट डेटा

ग्राफ से, हम देखते हैं कि:

  • सीपीयू इंटेंसिव सिंगल कोर एप्लिकेशन के लिए, दीवार और उपयोगकर्ता लगभग एक ही हैं

  • 2 कोर के लिए, उपयोगकर्ता 2x दीवार के बारे में है, जिसका अर्थ है कि उपयोगकर्ता का समय सभी थ्रेड्स में गिना जाता है।

    उपयोगकर्ता मूल रूप से दोगुना हो गया, और जबकि दीवार एक ही रही।

  • यह 8 थ्रेड तक जारी रहता है, जो मेरे कंप्यूटर में मेरे हाइपरथ्रेड्स की संख्या से मेल खाता है।

    8 के बाद, दीवार के रूप में अच्छी तरह से वृद्धि शुरू होती है, क्योंकि हमारे पास किसी भी अतिरिक्त सीपीयू को एक निश्चित समय में अधिक काम नहीं करना पड़ता है!

    इस बिंदु पर अनुपात पठार।

ध्यान दें कि यह ग्राफ केवल इतना स्पष्ट और सरल है क्योंकि काम विशुद्ध रूप से सीपीयू बाध्य है: अगर यह स्मृति बाध्य कर रहे थे, तो हम बहुत पहले ही कम कोर के साथ प्रदर्शन में गिरावट मिलेगा क्योंकि स्मृति पहुंच अड़चन के रूप में दिखाया गया होगा क्या क्या "सीपीयू बाउंड" और "आई / ओ बाउंड" शब्द का अर्थ है?

के साथ भारी काम करता है sendfile

सबसे भारी एसईएस कार्यभार जिसके साथ मैं आ सकता था, का उपयोग करना था sendfile, जो कर्नेल स्थान पर फ़ाइल कॉपी ऑपरेशन करता है: किसी फ़ाइल को किसी सुरक्षित, सुरक्षित और कुशल तरीके से कॉपी करें

तो मैंने सोचा कि यह इन-कर्नेल memcpyएक सीपीयू गहन ऑपरेशन होगा।

पहले मैं एक बड़ी 10GiB यादृच्छिक फ़ाइल के साथ आरंभ करता हूं:

dd if=/dev/urandom of=sendfile.in.tmp bs=1K count=10M

फिर कोड चलाएँ:

#define _GNU_SOURCE
#include <assert.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/sendfile.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char **argv) {
    char *source_path, *dest_path;
    int source, dest;
    struct stat stat_source;
    if (argc > 1) {
        source_path = argv[1];
    } else {
        source_path = "sendfile.in.tmp";
    }
    if (argc > 2) {
        dest_path = argv[2];
    } else {
        dest_path = "sendfile.out.tmp";
    }
    source = open(source_path, O_RDONLY);
    assert(source != -1);
    dest = open(dest_path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
    assert(dest != -1);
    assert(fstat(source, &stat_source) != -1);
    assert(sendfile(dest, source, 0, stat_source.st_size) != -1);
    assert(close(source) != -1);
    assert(close(dest) != -1);
    return EXIT_SUCCESS;
}

गिटहब ऊपर

जो मूल रूप से उम्मीद के मुताबिक ज्यादातर सिस्टम समय देता है:

real    0m2.175s
user    0m0.001s
sys     0m1.476s

मैं यह देखने के लिए भी उत्सुक था कि timeक्या विभिन्न प्रक्रियाओं के syscalls के बीच अंतर होगा, इसलिए मैंने कोशिश की:

time ./sendfile.out sendfile.in1.tmp sendfile.out1.tmp &
time ./sendfile.out sendfile.in2.tmp sendfile.out2.tmp &

और परिणाम था:

real    0m3.651s
user    0m0.000s
sys     0m1.516s

real    0m4.948s
user    0m0.000s
sys     0m1.562s

Sys का समय दोनों के लिए एक ही प्रक्रिया के लिए समान है, लेकिन दीवार का समय बड़ा है क्योंकि प्रक्रिया डिस्क एक्सेस की संभावना के लिए प्रतिस्पर्धा कर रही है।

तो ऐसा लगता है कि यह वास्तव में खाता है जिसके लिए प्रक्रिया किसी दिए गए कर्नेल का काम शुरू करती है।

बैश स्रोत कोड

जब आप सिर्फ time <cmd>उबंटू पर करते हैं , तो यह बैश कीवर्ड का उपयोग करता है जैसा कि देखा जा सकता है:

type time

कौन से आउटपुट:

time is a shell keyword

इसलिए हम आउटपुट स्ट्रिंग के लिए बैश 4.19 सोर्स कोड में grep स्रोत:

git grep '"user\b'

जो हमें execute_cmd.c फ़ंक्शन की ओर ले जाता है time_command, जो उपयोग करता है:

  • gettimeofday()और getrusage()अगर दोनों उपलब्ध हैं
  • times() अन्यथा

जिनमें से सभी Linux सिस्टम कॉल और POSIX फ़ंक्शन हैं

GNU Coreutils स्रोत कोड

अगर हम इसे कहते हैं:

/usr/bin/time

इसके बाद यह GNU Coreutils कार्यान्वयन का उपयोग करता है।

यह थोड़ा अधिक जटिल है, लेकिन प्रासंगिक स्रोत resuse.c पर लगता है और यह करता है:

  • wait3यदि उपलब्ध हो तो एक गैर-पॉसिक्स बीएसडी कॉल
  • timesऔर gettimeofdayअन्यथा

14

रियल एक प्रक्रिया के लिए कुल बारी-बारी के समय को दिखाता है; जबकि उपयोगकर्ता उपयोगकर्ता-निर्धारित निर्देशों के लिए निष्पादन समय दिखाता है और सिस्टम कॉल निष्पादित करने के लिए Sys समय के लिए है!

वास्तविक समय में प्रतीक्षा समय भी शामिल है (I / O आदि के लिए प्रतीक्षा समय)

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