2008-10-10 14 views
69

मैं एक परियोजना के लिए मेमोरी मैप की गई फाइलों का शोध कर रहा हूं और उन लोगों के किसी भी विचार की सराहना करता हूं जिन्होंने पहले उन्हें इस्तेमाल किया है, या उनका उपयोग करने का फैसला किया है, और क्यों?स्मृति-मैप की गई फ़ाइलों के क्या फायदे हैं?

विशेष रूप से, मैं निम्नलिखित के बारे में चिंतित हूँ, महत्व के क्रम में:

  • संगामिति
  • रैंडम एक्सेस
  • प्रदर्शन उपयोग
  • पोर्टेबिलिटी

उत्तर

44

मुझे लगता है कि लाभ वास्तव में है कि आप फ़ाइल पढ़ने के पारंपरिक तरीकों से आवश्यक डेटा प्रतिलिपि की मात्रा को कम करते हैं।

यदि आपका एप्लिकेशन मेमोरी-मैप की गई फ़ाइल में "जगह में" डेटा का उपयोग कर सकता है, तो यह कॉपी किए बिना आ सकता है; यदि आप सिस्टम कॉल का उपयोग करते हैं (उदा। लिनक्स के प्रीड()) तो आम तौर पर कर्नेल को डेटा को अपने स्वयं के बफर से उपयोगकर्ता स्थान में कॉपी करना शामिल होता है। इस अतिरिक्त प्रतिलिपि में न केवल समय लगता है, बल्कि डेटा की इस अतिरिक्त प्रति को एक्सेस करके सीपीयू के कैश की प्रभावशीलता को कम करता है।

यदि डेटा को वास्तव में डिस्क से (जैसे भौतिक I/O) में पढ़ना है, तो ओएस को अभी भी उन्हें पढ़ना होगा, पेज गलती शायद सिस्टम कॉल से बेहतर प्रदर्शन नहीं है , लेकिन अगर वे नहीं (यानी पहले से ही ओएस कैश में), सिद्धांत सिद्धांत में बेहतर होना चाहिए।

डाउनसाइड पर, स्मृति-मैप की गई फ़ाइलों के लिए कोई असीमित इंटरफ़ेस नहीं है - यदि आप उस पृष्ठ तक पहुंचने का प्रयास करते हैं जिसमें मैप नहीं किया गया है, तो यह पृष्ठ की गलती उत्पन्न करता है और थ्रेड I/O के लिए प्रतीक्षा करता है।


स्मृति मैप की गई फ़ाइलों के लिए स्पष्ट नुकसान एक 32-बिट ओएस पर है - आप आसानी से पता स्थान से बाहर चला सकते हैं।

+2

अच्छा Windows पर कम से कम आप एक बड़ा mmap फ़ाइल के एकाधिक 32 बिट विचारों मैप कर सकते हैं - जो नियमित रूप से CRT समारोह –

+0

@MarkR आप ने लिखा है "अपने अतिरिक्त नकल न केवल समय लगता है का उपयोग करते हुए बहुत बड़ी फ़ाइलों से निपटने के लिए कोशिश कर रहा से अधिक कुशल हो सकता है , लेकिन ** डेटा की इस अतिरिक्त प्रति को एक्सेस करके सीपीयू के कैश की प्रभावशीलता को कम करता है। ** "। (** जोर ** मेरा)। क्या आप कृपया बता सकते हैं कि कर्नेल में अतिरिक्त बफर प्रतिलिपि कैसे सीपीयू के कैश की प्रभावशीलता में बाधा डालती है? – Geek

+2

@ गीक दो गुना अधिक स्मृति तक पहुंच = दो बार जितना कैश बर्बाद हो गया (बहुत लगभग)। – immibis

1
की
  • आसानी

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

    मैं एक लंबे समय पहले एक सूर्य सिस्टम पर उन्हें का उपयोग किया है, और उन मेरे विचार कर रहे हैं।

  • 18

    मेमोरी मैप की फ़ाइलों के लिए इस्तेमाल किया जा सकता है या तो पढ़ने/लिखने का उपयोग, या समवर्ती साझा करने का समर्थन करने के बदलें। जब आप उन्हें एक तंत्र के लिए उपयोग करते हैं, तो आप दूसरे को भी प्राप्त करते हैं।

    बल्कि lseeking और लेखन और एक फाइल में चारों ओर पढ़ने से, आप इसे स्मृति में नक्शा और बस बिट्स जहाँ आप उन्हें होने की उम्मीद एक्सेस करते हैं।

    यह बहुत आसान हो सकता है, और आभासी स्मृति इंटरफ़ेस के आधार पर प्रदर्शन में सुधार कर सकते हैं। प्रदर्शन सुधार हो सकता है क्योंकि ऑपरेटिंग सिस्टम अब आपके सभी अन्य प्रोग्राममैटिक मेमोरी एक्सेस के साथ इस पूर्व "फ़ाइल I/O" को प्रबंधित करता है, और (सिद्धांत रूप में) पेजिंग एल्गोरिदम का लाभ उठा सकता है और आगे यह है कि यह पहले से ही समर्थन के लिए उपयोग कर रहा है आपके प्रोग्राम के आराम के लिए वर्चुअल मेमोरी। हालांकि, यह आपके अंतर्निहित वर्चुअल मेमोरी सिस्टम की गुणवत्ता पर निर्भर करता है। मैंने सुना है कि सोलारिस और * बीएसडी वर्चुअल मेमोरी सिस्टम लिनक्स की वीएम प्रणाली की तुलना में बेहतर प्रदर्शन सुधार दिखा सकते हैं - लेकिन मेरे पास इसका समर्थन करने के लिए कोई अनुभवजन्य डेटा नहीं है। YMMV। जब आप मैप किए गए स्मृति के माध्यम से एक ही "फाइल" का उपयोग कर कई प्रक्रियाओं की संभावना पर विचार

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

    मैप की दुनिया में, इसके विपरीत में, दो प्रक्रियाओं दोनों "लेखन" कल्पना। वे "मेमोरी स्टोर्स" कर ऐसा करते हैं, जिसके परिणामस्वरूप ओ/एस डेटा को डिस्क पर डेटा पेजिंग करता है - अंततः। लेकिन इस बीच, अतिव्यापी लेखन होने की उम्मीद की जा सकती है।

    यहां एक उदाहरण है। मान लें कि मेरे पास ऑफ़सेट 1024 पर 8 बाइट्स लिखने दोनों की दो प्रक्रियाएं हैं। प्रक्रिया 1 '11111111' लिख रही है और प्रक्रिया 2 '22222222' लिख रही है। यदि वे फ़ाइल I/O का उपयोग करते हैं, तो आप कल्पना कर सकते हैं, ओ/एस में गहराई से, 1 बजे से भरा बफर है, और 2 बजे से भरा बफर, दोनों डिस्क पर एक ही स्थान पर जाते हैं। उनमें से एक पहले वहाँ जा रहा है, और दूसरा एक सेकंड। इस मामले में, दूसरा जीतता है। हालांकि, अगर मैं मेमोरी-मैप किए गए फ़ाइल दृष्टिकोण का उपयोग कर रहा हूं, तो प्रक्रिया 1 4 बाइट्स की मेमोरी स्टोर जा रही है, इसके बाद 4 बाइट्स की एक और मेमोरी स्टोर है (मान लीजिए कि अधिकतम मेमोरी स्टोर आकार नहीं है)।प्रक्रिया 2 वही काम करेगा। जब प्रक्रियाओं को चलाने के आधार पर, आप निम्न में से किसी को देखने की उम्मीद कर सकते हैं:

    11111111 
    22222222 
    11112222 
    22221111 
    

    इस का हल स्पष्ट पारस्परिक अपवर्जन उपयोग करने के लिए है - जो शायद किसी भी घटना में एक अच्छा विचार है। आप ओ/एस पर पढ़ने/लिखने वाली फ़ाइल I/O मामले में "सही चीज़" करने के लिए भरोसा करते थे, वैसे भी।

    वर्गीकरण पारस्परिक बहिष्कार आदिम म्यूटेक्स है। मेमोरी मैप की गई फ़ाइलों के लिए, मैं सुझाव दूंगा कि आप मेमोरी-मैप किए गए म्यूटेक्स को देखें, उदाहरण के लिए (उदा।) Pthread_mutex_init()।

    एक गोचा के साथ संपादित करें: जब आप मैप की गई फ़ाइलों का उपयोग कर रहे हैं, फ़ाइल में डेटा में पॉइंटर्स को एम्बेड करने का एक प्रलोभन है, फ़ाइल में (मैप किए गए फ़ाइल में संग्रहीत लिंक की गई सूची)। आप ऐसा नहीं करना चाहते हैं, क्योंकि फाइल अलग-अलग समय पर अलग-अलग पूर्ण पते पर या विभिन्न प्रक्रियाओं में मैप की जा सकती है। इसके बजाय, मैप किए गए फ़ाइल के भीतर ऑफ़सेट का उपयोग करें।

    43

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

    रनटाइम पर फ़ाइल मेमोरी मैप की गई है, C -स्टाइल struct सरणी पर डाली गई है, और हम मिलान प्रकारों को उपयोगकर्ता प्रकार के रूप में ढूंढने के लिए बाइनरी खोज करते हैं। फ़ाइल के केवल कुछ मेमोरी पेज वास्तव में डिस्क से पढ़े जाते हैं - जो भी पृष्ठ बाइनरी खोज के दौरान मारा जाता है।

    • Concurrency - मेरे पास एक कार्यान्वयन समस्या थी जहां कभी-कभी उसी प्रक्रिया स्थान में फ़ाइल को कई बार मेमोरी मैप किया जाता था। यह एक समस्या थी क्योंकि मुझे याद है क्योंकि कभी-कभी सिस्टम को फ़ाइल को मैप करने के लिए वर्चुअल मेमोरी का एक बड़ा पर्याप्त ब्लॉक नहीं मिल सका। समाधान केवल एक बार फ़ाइल को मैप करना था और सभी कॉलों को थंकना था। एक पूर्ण उड़ा विंडोज सेवा का उपयोग कर पूर्वदर्शी में ठंडा हो जाएगा।
    • यादृच्छिक अभिगम - बाइनरी खोज निश्चित रूप से यादृच्छिक पहुंच और बिजली तेज है
    • प्रदर्शन - लुकअप बेहद तेज़ है। जैसे-जैसे उपयोगकर्ता पॉपअप विंडो टाइप करते हैं, मिलान करने वाले उत्पाद भाग संख्याओं की एक सूची प्रदर्शित करता है, इसलिए सूची टाइप होने पर सूची घट जाती है। टाइप करते समय कोई ध्यान देने योग्य अंतराल नहीं है।
    +1

    द्विआधारी खोज धीमा नहीं होगा के रूप में पृष्ठों प्रत्येक प्रयास के लिए में पढ़ा रहे हैं? या ऑपरेटिंग सिस्टम एक कुशल तरीके से इस से निपटने के लिए पर्याप्त स्मार्ट है? – jjxtra

    +1

    मुझे लगता है का उपयोग कर स्मृति मैप की आई/ओ द्विआधारी खोज के लिए एक तरह से बेकार है, के रूप में खोज केवल अपेक्षाकृत दूर स्मृति स्थल में कुछ ही कुंजी का उपयोग करेंगे, लेकिन ओएस इस तरह के प्रत्येक अनुरोध के लिए 4k पन्नों में लोड होगा। लेकिन फिर, भागों के साथ फ़ाइल ज्यादा नहीं बदलती है, इसलिए कैश इसे कवर करने में मदद करता है। लेकिन सख्ती से बोलते हुए, मेरा मानना ​​है कि यहां पारंपरिक मांग/पढ़ना बेहतर होगा। अंत में, इन दिनों 1 मिलियन ज्यादा नहीं है। क्यों न सिर्फ इसे रैम में रखें? –

    +2

    @ स्वाइन और साइकोडाड मेरा मूल उत्तर 2008 से था और इस मेमोरी मैप किए गए ऑटो-पूर्ण सुविधा का वास्तविक कार्यान्वयन 2004-2005 या उससे भी कम था। पूरी फाइल लोड करने के लिए 800-1000 एमबी भौतिक मेमोरी का उपभोग हमारे उपयोगकर्ता आधार के लिए एक अच्छा समाधान नहीं था। मेमोरी मैप किए गए समाधान बहुत तेज़ और कुशल थे। यह लात-गधे और मुझे अपने प्रारंभिक जूनियर-डेवलपर दिनों से प्यार से याद है। :) –

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