2009-09-07 19 views
9

आउटपुट दर हार्ड डिस्क लेखन दर से अधिक कैसे हो सकती है?पर्ल: लिखने की गति रहस्य?

अद्यतन 1:

  1. बंद कर दिया एंटीवायरस: मैं निम्नलिखित बदल दिया है। कोई परिवर्तन नहीं होता है।

  2. नई भौतिक डिस्क डाली और परीक्षण के लिए पहले विभाजन का उपयोग किया। (प्रारंभिक परीक्षण के लिए डिस्क सिस्टम विभाजन से अलग अंतिम विभाजन पर थी, लेकिन उसी भौतिक डिस्क पर ।)। परिणाम: एक ही चक्रीय पैटर्न है, लेकिन सिस्टम अब परीक्षण के दौरान उत्तरदायी नहीं है। लिखने की गति कुछ हद तक अधिक है (पहले विभाजन का उपयोग करने के कारण हो सकती है और/या सिस्टम विभाजन के साथ हस्तक्षेप नहीं कर सकता है)। प्रारंभिक निष्कर्ष: सिस्टम विभाजन से हस्तक्षेप के कुछ प्रकार थे।

  3. 64 बिट पर्ल स्थापित किया गया। चक्र चले गए हैं और सब कुछ 2 सेकंड टाइमकेल पर स्थिर है: 55% सीपीयू एकल कोर, 65 एमबी/एस के बारे में लिखने की गति।

  4. 64 बिट पर्ल के साथ मूल ड्राइव पर प्रयास किया। परिणाम: कहीं बीच में। 8 सेकंड के चक्र, सीपीयू 20-50%, 35 - 65 एमबी/सेकंड (0-100% के गहरे चक्र के बजाय, 0 - 120 एमबी/सेकंड)। प्रणाली केवल हल्के से उत्तरदायी नहीं है। लिखें गति 50 एमबी/सेकंड है। यह हस्तक्षेप सिद्धांत का समर्थन करता है।

  5. पर्ल स्क्रिप्ट में फ़्लशिंग। अभी तक कोशिश नहीं की


ठीक है, मैं अतीत first hurdle मिला है। मैं एक पर्ल स्क्रिप्ट कि एक बहुत बड़े पाठ फ़ाइल उत्पन्न कर सकते हैं लिखा है (उदाहरण के लिए 20 जीबी) और अनिवार्य रूप से बस के एक नंबर है:

print NUMBERS_OUTFILE $line; 

जहां $ लाइन पर एक "\ n" के साथ एक लंबी स्ट्रिंग है समाप्त।

जब पर्ल स्क्रिप्ट शुरू होता है लिखने दर है के बारे में 120 MB/s (क्या स्क्रिप्ट के द्वारा की जाती है के बीच संगत, Process Explorer और "आईओ बाइट्स/सेकंड लिखें" प्रक्रिया के लिए पर्ल प्रदर्शन मॉनिटर में।) और 100 एकल कोर पर% CPU यह चालू है। यह दर, मुझे विश्वास है, हार्ड डिस्क की गति लिखने से अधिक है।

फिर कुछ समय बाद (उदाहरण के लिए 20 सेकंड और 2.7 जीबी लिखित) पूरी प्रणाली बहुत ही उत्तरदायी हो जाती है और सीपीयू 0% पर गिर जाती है। उदाहरण के लिए यह आखिरी 30 सेकंड। इन दो चरणों में औसत लिखने की गति हार्ड डिस्क की की गति गति के अनुरूप है। इस पैराग्राफ में वर्णित समय और आकार रन से चलाने के लिए बहुत भिन्न होते हैं। पहले चरण के लिए 1 जीबी से 4.3 जीबी तक अब तक देखा गया है। यहां एक transcript for the run with 4.3 GB है।

वहाँ एक 9.2 जीबी पाठ फ़ाइल परीक्षण में उत्पन्न करने के लिए इन चक्रों के कई प्रकार हैं:

Enter image description here

क्या चल रहा है?


पूर्ण Perl script और BAT driver script (एचटीएमएल पूर्व टैग के साथ प्रारूपित)। यदि दो पर्यावरण चर एमबीएसआईजेई और आउटफाइल सेटअप हैं तो पर्ल स्क्रिप्ट को विंडोज़ की तुलना में अन्य प्लेटफॉर्म पर अपरिवर्तित करने में सक्षम होना चाहिए।

प्लेटफार्म: सक्रियस्टेट से पर्ल 5.10.0; (शुरुआत में 32 बिट, बाद में 64 बिट); 1004 बनाएँ। विंडोज एक्सपी x64 एसपी 2, कोई पेज फ़ाइल, 8 जीबी रैम, एएमडी क्वाड कोर सीपीयू, 500 जीबी ग्रीन कैवियार हार्ड डिस्क (लिखने की गति 85 एमबी/एस?)।

उत्तर

5

मैं बाकी सब जो कह रहा है समस्या बफ़र्स भरने और फिर खाली है उस के साथ कर रहा हूँ।एक बफर (पर्ल में) होने से बचाने के autoflush को चालू करने का प्रयास करें:

#!/usr/bin/perl 

use strict; 
use warnings; 

use IO::Handle; 

my $filename = "output.txt"; 

open my $numbers_outfile, ">", $filename 
    or die "could not open $filename: $!"; 

$numbers_outfile->autoflush(1); 

#each time through the loop should be 1 gig 
for (1 .. 20) { 
    #each time though the loop should be 1 meg 
    for (1 .. 1024) { 
     #print 1 meg of Zs 
     print {$numbers_outfile} "Z" x (1024*1024) 
    } 
} 

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

+0

धन्यवाद। मैंने अब 64 बिट पर्ल (अद्यतन प्रश्न देखें) की कोशिश की है, लेकिन अगला चरण ऑटोफ्लश चालू करने का प्रयास करेगा। –

+0

याद रखें, अगर आप बफर को चारों ओर रखते हैं तो आपको अपने फाइल सिस्टम को संशोधित करने की भी आवश्यकता हो सकती है। –

+1

ऑटोफ्लश प्रत्येक प्रिंट तत्व के बाद सिस्टम कॉल करेगा। आपके उदाहरण में प्रदर्शन अच्छा होगा क्योंकि यह एक समय में 1 एमबी है। लेकिन अगर आप 'ए', 'बी', 'सी', 'डी' प्रिंट करते हैं तो यह बहुत बुरा होगा क्योंकि यह एक चार की चार सिस्टम कॉल है ... इसके लिए देखें। –

5

भौतिक डिस्क में प्रभावी ढंग से डालने से पहले सभी डेटा बफर में कैश किए जाते हैं। सिस्टम से एक बफर, डिस्क के अंदर एक और (32 एमबी बफर शायद)। जब आप उन बफर को भरते हैं, तो आपका प्रोग्राम पूर्ण गति और 100% CPU पर चलता है। एक बार बफर भरने के बाद, आपके प्रोग्राम को डिस्क के लिए इंतजार करना पड़ता है, जो स्मृति और बफर से बहुत धीमी है, और यह प्रतीक्षा आपको इस सीपीयू को उपभोग करने से रोकती है।

शायद आप fflush() के समतुल्य कुछ पर्ल का उपयोग करके, "डिस्क के लिए प्रतीक्षा करें" अपना कोड बना सकते हैं।

+0

मुझे उम्मीद है कि वहां फ़ाइल बफर होंगे। लेकिन आकार में कई जीबी नहीं (?) –

+4

लिनक्स सिस्टम बफर पर आमतौर पर लगभग सभी फ्री रैम में फैलाने के लिए कॉन्फ़िगर किया जाता है। –

+0

वह लिनक्स का उपयोग नहीं करता है ... –

4

शायद ओएस डिस्क पर जितना तेज़ हो सके (85 एमबी/एस), और एक बफर में अतिरिक्त 35 एमबी/एस डाल रहा है, और जब यह भरता है, तो ऐप को बफर को फ्लश करने के लिए रोक रहा है। चूंकि बफर 85 एमबी/एस पर निकाला जाता है, इसलिए आप इसे भरने के लिए निकालने के लिए 35/85 = ~ 0.4 गुना लेने की उम्मीद करेंगे। यह आपके ग्राफ के साथ व्यापक रूप से संगत है, अगर मैं पर्याप्त squint।

आप बफर के आकार को विराम समय और डिस्क की गति के उत्पाद के रूप में अनुमानित कर सकते हैं।

3

ग्राफ को देखो! हरी रेखा औसत डिस्क कतार लंबाई इंगित करती है। एक पल में, यह एक चोटी हो जाता है और सीपीयू बाद में 0 पर जाता है। आईओ राइट्स भी 0 पर जाता है। यह दूसरी चोटी दिखाए जाने तक सामान्य हो जाता है। फिर सीपीयू और आईओ सामान्य पर लौटते हैं। फिर आईओ और सीपीयू दोनों फिर से ड्रॉप, अगले कतार चोटी पर फिर से ऊपर जाने के लिए। और फिर नीचे, फिर फिर से ...

यह हो सकता है कि डिस्क उस समय भौतिक लिख रही है। हालांकि, यह भी हो सकता है कि सिस्टम उस पल में डिस्क सत्यापन कर रहा है, यह लिखने के लिए कि यह सिर्फ लिखने के लिए लिखा गया है, यह सुनिश्चित कर रहा है कि डेटा सही ढंग से लिखा गया है।

मुझे लगता है कि एक और चीज 2.7 जीबी आकार है। चूंकि आप इसे विंडोज सिस्टम पर चला रहे हैं, इसलिए मैं थोड़ा संदिग्ध हो जाता हूं क्योंकि यह 32-बिट प्रक्रिया के रूप में विंडोज़ को संभालने वाली स्मृति की मात्रा के बारे में है। 64-बिट विंडोज़ 3 जीबी रैम तक एप्लिकेशन प्रदान करेगा (थोड़ी कम) लेकिन फिर इसे फिर से रिलीज करने की जरूरत है। आप उपयोग में रैम की मात्रा और आईओ पढ़ने की मात्रा की जांच करने के लिए प्रक्रिया एक्सप्लोरर का उपयोग करना चाह सकते हैं।

और शायद एक 64-बिट पर्ल संस्करण का उपयोग करें ...

+0

2.7 जीबी के बारे में: मुझे नहीं पता कि 3 जीबी से अधिक संभव है, लेकिन यह पहले से ही 1 जीबी पर हो सकता है। उदाहरण के लिए मैंने इसे लिखने से पहले मैंने इसे फिर से चलाया और पहला चरण 1.2 जीबी (कहीं 1139 एमबी और 1273 एमबी के बीच) में समाप्त हुआ। –

+0

रैम की मात्रा से आपका क्या मतलब है? पर्ल प्रक्रिया के लिए राशि? पर्ल प्रक्रिया के लिए "निजी बाइट्स" रन के दौरान 4 एमबी पर स्थिर रहता है। स्क्रिप्ट शुरू होने पर लगभग 6.3 जीबी रैम मुक्त है। –

+0

मैंने अभी एक और रन की कोशिश की। इस बार पहला चरण लगभग 4.3 जीबी (कहीं 4.1 9 जीबी और 4.41 जीबी के बीच में समाप्त हुआ [4288.3 एमबी; 4513.7 एमबी])। यहां रन की एक प्रतिलिपि है: http://www.pil.sdu.dk/1/until2039-12-31/PerlPerfTranscript_2009-09-07b.txt –

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