2011-12-23 11 views
5

memcpy/memmove डुप्लिकेट (डेटा कॉपी करें) स्रोत से गंतव्य तक। स्रोत डेटा की बाइट प्रति द्वारा वास्तविक बाइट किए बिना पृष्ठों को एक आभासी पते से दूसरे में स्थानांतरित करने के लिए कुछ भी मौजूद है? ऐसा लगता है कि मेरे लिए पूरी तरह से संभव है, लेकिन क्या कोई ऑपरेटिंग सिस्टम वास्तव में इसकी अनुमति देता है? यह मेरे लिए अजीब लगता है कि गतिशील सरणी इतनी व्यापक और लोकप्रिय अवधारणा है, लेकिन शारीरिक रूप से प्रतिलिपि करके उन्हें बढ़ाना इतना अप्रिय ऑपरेशन है। यह सिर्फ पैमाने पर नहीं होती है (उदाहरण के लिए एक 200GB सरणी में एक 100GB सरणी बढ़ रहा कल्पना। यही कारण है कि एक समस्या यह है कि अब < $ 10K रेंज में सर्वर पर पूरी तरह से संभव है।क्या कोई ओएस शारीरिक रूप से प्रतिलिपि किए बिना एक पते से दूसरे पते पर स्मृति को स्थानांतरित करने की अनुमति देता है?

void* very_large_buffer = VirtualAlloc(NULL, 2GB, MEM_COMMIT); 
// Populate very_large_buffer, run out of space. 
// Allocate buffer twice as large, but don't actually allocate 
// physical memory, just reserve the address space. 
void* even_bigger_buffer = VirtualAlloc(NULL, 4GB, MEM_RESERVE); 
// Remap the physical memory from very_large_buffer to even_bigger_buffer without copying 
// (i.e. don't copy 2GB of data, just copy the mapping of virtual pages to physical pages) 
// Does any OS provide support for an operation like this?  
MoveMemory(very_large_buffer, even_bigger_buffer, 2GB) 
// Now very_large_buffer no longer has any physical memory pages associated with it 
VirtualFree(very_large_buffer) 

उत्तर

6

के विभिन्न दृश्यों के मानचित्रण कुछ हद तक से प्रक्रिया के बीच स्मृति नकल है, तो आप ऐसा कर सकते हैं mremap लिनक्स पर साथ।

कि नाटकों फोन प्रक्रिया की पृष्ठ तालिका के साथ एक शून्य प्रतिलिपि reallocation करने के लिए अगर यह कर सकते हैं। सभी मामलों में यह संभव नहीं है (पता स्थान विखंडन, और बस अन्य मौजूदा मैपिंग की उपस्थिति एक मुद्दा है)।

आदमी पृष्ठ वास्तव में कहना है कि यह:

mremap() आभासी पते और स्मृति पृष्ठों के बीच मानचित्रण बदल जाता है। इसका उपयोग एक बहुत ही कुशल रीयलोक (3) को लागू करने के लिए किया जा सकता है।

+0

ऐसा लगता है कि यह वही है जो मैं ढूंढ रहा हूं। मैं इसे लिनक्स और हर जगह मानक गूंगा स्मृति प्रतिलिपि पर उपयोग कर सकता हूं। – Eloff

+1

या एक realloc और उम्मीद है कि यह हुड के तहत एक समान विधि का उपयोग करता है। :) – onitake

2
गीगाबाइट में सरणी आकार के बारे में बात शुरू करते हैं

हाँ, यह स्मृति का एक आम उपयोग 'चाल' को मैप किया फाइल या फ़ाइल

0

मेरा मतलब है, आप पूरी तरह से गारंटी नहीं दे पाएंगे कि अगले 100 जीबी में कोई सक्रिय स्मृति नहीं होगी, इसलिए हो सकता है कि आप इसे संगत नहीं कर पाएंगे।

दूसरी ओर, आप एक रैग किए गए सरणी (सरणी की एक सरणी) का उपयोग कर सकते हैं जहां सरणी एक दूसरे के पास नहीं होनी चाहिए (या यहां तक ​​कि एक ही आकार)। गतिशील सरणी के कई फायदे 100 जीबी क्षेत्र में स्केल नहीं हो सकते हैं।

+1

मेरी समझ यह है कि वास्तविक भौतिक RAM पृष्ठों को संगत नहीं होना चाहिए, यह वर्चुअल एड्रेसिंग का बिंदु है। लेकिन आपको 200 जीबी गैर-खंडित वर्चुअल एड्रेस स्पेस की आवश्यकता होगी (वर्तमान में 64 बिट प्रक्रियाओं में आधुनिक ऑपरेटिंग सिस्टम में 8TB पता स्थान है, इसलिए यह कोई मुद्दा नहीं होना चाहिए।) – Eloff

1

प्रत्येक पॉज़िक्स सिस्टम ऐसा करने में सक्षम है। यदि आप फ़ाइल डिस्क्रिप्टर (open या shm_open द्वारा प्राप्त) के साथ mmap का उपयोग करते हैं और अनामिक रूप से आप इसे अनैप नहीं कर सकते हैं, तो छंटनी (संकीर्ण या बढ़ें) और फिर इसे फिर से मैप करें। आप एक ही पृष्ठ के लिए अक्सर एक अलग आभासी पता प्राप्त कर सकते हैं।

+0

अगर मैं गलत हूं तो मुझे सही करें, लेकिन अनैपिंग सभी गंदे लिखेंगे पृष्ठ उस फ़ाइल पर वापस आते हैं (आलसी?) तो जब आप इसे फिर से मैप करते हैं, तो पृष्ठों तक पहुंचने से उन्हें फ़ाइल से वापस पढ़ने की आवश्यकता हो सकती है। वहां बहुत सारे कार्यान्वयन विस्तार हैं, लेकिन डिस्क आईओ के कारण स्मृति प्रतियों से परहेज करना एक जीत होने की संभावना नहीं है। हालांकि मैं उत्सुक हूं, चूंकि एमएमएपी अक्सर प्रक्रियाओं के बीच स्मृति साझा करने के लिए प्रयोग किया जाता है, इसलिए फ़ाइल को बढ़ाना संभव नहीं है (फ़ाइल को कम नहीं करना चाहिए) और पहले मैपिंग को बंद किए बिना उसी फ़ाइल का दूसरा मैपिंग बनाना संभव नहीं है? यह एक शून्य चाल प्रतिलिपि होगी जो मुझे लगता है। – Eloff

+0

सबसे पहले, यदि आप 'shm_open' का उपयोग करते हैं तो कोई फ़ाइल नहीं है, इसलिए इसमें कुछ भी लिखा नहीं जा सकता है। और यहां तक ​​कि 'ओपन' के लिए भी मुझे नहीं लगता कि अनैपिंग पेजों को वापस लिखेगी, केवल फाइल डिस्क्रिप्टर को बंद करने से यह लागू होगा। –

+0

मुझे लगता है कि shm_open मामले में आप सामग्री को खो नहीं पाएंगे क्योंकि आपने इसे अनैप किया है, यह दिलचस्प है। और आप सही हैं मुझे लगता है कि गंदे पृष्ठ सिर्फ इसलिए नहीं लिखे जाएंगे क्योंकि आपने मैपिंग बंद कर दी है, यह अभी भी सिस्टम लिखने वाले बफर में होना चाहिए। – Eloff