2013-02-08 81 views
5

पर C++ का उपयोग करके ढेर पर 2 जीबी से अधिक आवंटित करें यह एक बहुत ही आम समस्या प्रतीत होता है, लेकिन फिर भी मुझे एक निश्चित उत्तर नहीं मिला है।32 बिट लिनक्स कर्नेल

मैं जो लिनक्स चलाता है एक सर्वर के लिए उपयोग किया, राम के 16 जीबी और एक 16-कोर (64 बिट) सीपीयू (/ proc/cpuinfo देता है "इंटेल (आर) जिऑन (आर) सीपीयू E5520 @ 2.27GHz" है)। हालांकि, कर्नेल 32 बिट है (uname -m i686 देता है)। बेशक, मेरे पास रूट रूट नहीं है, इसलिए मैं को बदल नहीं सकता।

मैं एक सी ++ चला रहा हूँ - कार्यक्रम मैंने लिखा है, जो कुछ स्मृति के भूखे गणना करता है, तो मैं मैं एक बड़े ढेर की जरूरत है - लेकिन जब भी मैं 2GB से अधिक हिस्सा आवंटित करने की कोशिश, मैं एक badalloc, हालांकि ulimit लाभ प्राप्त "असीमित"।

#include <iostream> 
#include <vector> 

int main() { 
    int i = 0; 
    std::vector<std::vector<int> > vv; 
    for (;;) { 
     ++i; 
     vv.resize(vv.size() + 1); 
     std::vector<int>* v = &(vv.at(vv.size() - 1)); 
     v->resize(1024 * 1024 * 128); 
     std::cout << i * 512 << " MB.\n"; 
    } 
    return 0; 
} 

जी ++ (कोई भी निशानी) के साथ संकलन के बाद, उत्पादन होता है: सादगी के लिए, हम सिर्फ इतना कहना मेरा कार्यक्रम यह है जाने

512 MB. 
1024 MB. 
1536 MB. 
2048 MB. 
terminate called after throwing an instance of 'std::bad_alloc' 
    what(): std::bad_alloc 
Aborted 

जहां तक ​​मैं समझता हूँ, इस की एक सीमा है 32 बिट सिस्टम, जाहिर है क्योंकि 32 बिट पॉइंटर केवल 2^32 अलग-अलग एड्रेस धारण कर सकता है (क्या मुझे लगता है कि अगर मैंने उसी सर्वर पर एक ही प्रोग्राम संकलित किया है, लेकिन उस सर्वर ने 64 बिट कर्नेल चलाया है, तो प्रोग्राम अधिक आवंटित कर सकता है 2 जीबी से?)

यह सवाल नहीं है कि आवंटित स्मृति संगत है, अगर मैं उदाहरण प्रोग्राम में पतला टुकड़ा करता हूं, तो वही समस्या होती है, और मेरे वास्तविक कार्यक्रम में मेमोरी का कोई बड़ा ब्लॉक नहीं है, केवल बहुत छोटे ।

तो मेरा प्रश्न है: क्या मैं कुछ भी कर सकता हूं? मैं ओएस नहीं बदल सकता, लेकिन निश्चित रूप से मैं अपने स्रोत कोड को संशोधित कर सकता हूं, विभिन्न कंपाइलर विकल्प आदि का उपयोग करें ... लेकिन मुझे 2 जीबी से अधिक मेमोरी की आवश्यकता है, सभी एक बार में, और अनुकूलित करने के लिए कोई स्पष्ट तरीका नहीं है कार्यक्रम का उपयोग करने वाले एल्गोरिदम।

यदि उत्तर स्पष्ट "नहीं" है, तो यह अभी भी जानना अच्छा होगा।

धन्यवाद, लुकास

+1

(1) एक 64 बिट ओएस और स्थानीय एप्लिकेशन का उपयोग करें। (2) [भौतिक पता एक्सटेंशन] सक्षम करें (http://en.wikipedia.org/wiki/Physical_Address_Extension#Operating_system_support) लक्ष्य मशीन पर समर्थन 32 बिट है। यह आपको काम करने के लिए एक अतिरिक्त जीबी खरीदना चाहिए। इस बात का लघु (जो ऐसा लगता है कि आप कुछ बहुत संकीर्ण संभावनाओं में पिन हो रहे हैं) एक स्व-प्रबंधित डिस्क पृष्ठ प्रणाली के अपने ही एकमात्र विकल्प हो सकता है। – WhozCraig

+0

* क्या मुझे लगता है कि यदि मैंने एक ही सर्वर पर एक ही प्रोग्राम को संकलित किया है, तो क्या यह सर्वर 64 बिट कर्नेल चला गया है, प्रोग्राम 2 जीबी से अधिक आवंटित कर सकता है? * - हाँ। आप * स्विच के साथ थोड़ा अधिक (शायद 3.5 जीबी या उससे भी अधिक) की तलाश कर सकते हैं। अनिवार्य रूप से, हालांकि आपने स्केलेबिलिटी समस्या को मारा है और यदि आप वास्तव में समय के साथ प्रसंस्करण को विभाजित नहीं कर पाते या सीमा को मारने से बचने के लिए प्रक्रिया है तो आपको 64 बिट पर जाना होगा। –

+0

क्या वह कई प्रक्रियाओं को 2 जीबी आवंटित करके इस समस्या को हल कर सकता है। फिर आवश्यकतानुसार अन्य प्रक्रिया के मेमोरी हिस्सों में डेटा पढ़ने/लिखने के लिए एक आईपीसी तंत्र का आविष्कार किया? या बस memcached के एक या एक से अधिक उदाहरण चलाते हैं? – selbie

उत्तर

5

आप स्मृति 64-बिट कर्नेल में बदल रहा है (जो, हाँ, आप करने की अनुमति होगी के बिना यह करने के लिए कोई रास्ता नहीं सभी को एक बार, नहीं, वहाँ वास्तव में है की जरूरत है एक ही प्रक्रिया में अधिक मेमोरी आवंटित करें)

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

उदाहरण के लिए यह अन्य प्रक्रिया में डेटा संग्रहीत करके काम कर सकता है, और जब आवश्यक हो तो आपकी प्रक्रिया अस्थायी रूप से उस प्रक्रिया से साझा मेमोरी को अपनी मेमोरी स्पेस में मैप कर सकती है। यह अभी भी स्मृति में संग्रहीत किया जाएगा, लेकिन स्मृति सीमा स्विच करते समय आपके ऊपर कुछ ओवरहेड होगा। यदि ओवरहेड स्वीकार्य है या नहीं, तो आपकी मेमोरी एक्सेस पैटर्न पर निर्भर करेगा।

यह बहुत सीधी आगे नहीं है, लेकिन कर्नेल को 64-बिट पता स्थान देने के बिना, ऐसा लगता है जैसे आप थोड़ा बाध्य हैं।

संपादित करें: आप कर्नेल को फिर से कॉन्फ़िगर द्वारा 2GB ऊपर एक छोटे से सीमा को बढ़ा कर सकता है, लेकिन यह केवल अर्थ है कि आप के बजाय वहाँ मुश्किल सीमा तक नहीं पहुंच जाएगा। इसके अलावा, इसके लिए रूट पहुंच की आवश्यकता होगी।

0

जवाब एक स्पष्ट "नहीं" है। यदि आप ओएस नहीं बदल सकते हैं, तो आप सीमा बढ़ा नहीं सकते हैं। सीमा एक पूरी प्रक्रिया के लिए लागू होता है और स्पष्ट रूप से कोई भी आवंटन प्रति प्रक्रिया की सीमा को पार कर सकते हैं।

कर्नेल संकलित करने के लिए इस्तेमाल किया विकल्पों के आधार पर, सीमा 2GB से अधिक हो सकता है, लेकिन निश्चित रूप 4GB की तुलना में कम हो जाएगा। लेकिन मुझे लगता है कि कर्नेल को फिर से सम्मिलित करना भी "ओएस को बदलना" के रूप में गिना जाता है।

this discussion

देखें और हाँ, एक 64-बिट ऑपरेटिंग सिस्टम है कि दूर जाना होगा की सीमा पर।