2010-03-18 12 views
7

previous question relating to heap usage restrictions से निम्नलिखित के बाद, मैं डेटा के बड़े सरणी से निपटने के लिए एक अच्छी मानक सी ++ कक्षा की तलाश में हूं, जो मेमोरी कुशल और गति कुशल दोनों है। मैं एक एकल मॉलोक/हीलअलोक का उपयोग करके सरणी आवंटित कर रहा था लेकिन विभिन्न कॉलों का उपयोग करके कई ट्रे के बाद, ढेर विखंडन की गड़बड़ी गिरती रहती है। तो मैं निष्कर्ष निकाला हूं, 64 बिट पर पोर्ट करने के अलावा, एक तंत्र का उपयोग करना है जो मुझे कई छोटी मेमोरी टुकड़ों को फैलाए जाने वाली बड़ी सरणी की अनुमति देता है। मैं प्रति तत्व एक आवंटित नहीं चाहता क्योंकि यह बहुत स्मृति अक्षम है, इसलिए योजना एक वर्ग लिखना है जो [] ऑपरेटर को ओवरराइड करता है और इंडेक्स के आधार पर उपयुक्त तत्व का चयन करता है। क्या ऐसा करने के लिए वहां पहले से ही एक सभ्य वर्ग है, या क्या मैं अपना खुद का रोलिंग बेहतर कर रहा हूं?तेजी से और मेमोरी कुशल तरीके से डेटा के बड़े सरणी से निपटने के लिए अच्छा सी ++ सरणी वर्ग?

मेरी समझ से, और कुछ googling, 32 बिट विंडोज़ प्रक्रिया सैद्धांतिक रूप से 2 जीबी तक का पता लगाने में सक्षम होना चाहिए। अब मानते हैं कि मेरे पास 2 जीबी इंस्टॉल है, और कई अन्य प्रक्रियाएं और सेवाएं 400 एमबी के बारे में सोच रही हैं, आपको लगता है कि मेरे प्रोग्राम को ढेर से कितनी उम्मीदवार मिल सकती है?

मैं वर्तमान में विजुअल सी ++ के विभिन्न स्वादों का उपयोग कर रहा हूं।

संपादित पोइटा पद के अनुसार, मैं एक std :: Deque की कोशिश की है, VS2008 पर निम्न परीक्षण का उपयोग कर;

#include <deque> 
using namespace std; 
struct V  
{ 
    double data[11]; 
}; 

struct T 
{ 
    long data[8];  
}; 


void dequeTest() 
{ 
    deque<V> VQ; 
    deque<T> TQ; 

    V defV; 
    T defT; 

    VQ.resize(4000000,defV); 
    TQ.resize(8000000,defT); 
} 

उपरोक्त डेटा के लिए कुल स्मृति 608MB में बाहर आता है, मैं सीधे malloc या HeapAlloc उपयोग करने के लिए गए थे, और < 1 सेकंड लेता है। डेक आकार का मूल रूप से 950 एमबी लिया गया, और फिर धीरे-धीरे वापस गिरना शुरू कर दिया। 15 मिनट बाद, डेकटेस्ट() ने प्रक्रिया के लिए केवल 6 एमबी मेमोरी का उपयोग करके समाप्त किया, जो शायद रन-टाइम के साथ अधिक था। मैंने विभिन्न पुश विकल्पों का उपयोग करके डेक को पॉप्युलेट करने का भी प्रयास किया, लेकिन प्रदर्शन इतना खराब था, मुझे जल्दी ही तोड़ना पड़ा। मैं संभवतः एक बेहतर प्रतिक्रिया प्राप्त करने के लिए डिफॉल्ट से बेहतर आवंटन प्रदान कर सकता हूं, लेकिन इसके चेहरे पर डेक इस नौकरी के लिए कक्षा नहीं है। ध्यान दें कि यह डेक के एमएस वीएस -2008 कार्यान्वयन से भी संबंधित हो सकता है, क्योंकि इस वर्ग में बहुत कुछ लगता है जो प्रदर्शन की बात करते समय बहुत ही कार्यान्वयन पर निर्भर करता है।

अपना खुद का बड़ा सरणी वर्ग लिखने का समय, मुझे लगता है।

दूसरा संपादित करें: आवंटन छोटी मात्रा के तुरंत बाद का उपयोग कर 1.875GB झुकेंगे;

#define TenMB 1024*1024*10 

void SmallerAllocs() 
{ 

    size_t Total = 0; 
    LPVOID p[200]; 
    for (int i = 0; i < 200; i++) 
    { 
     p[i] = malloc(TenMB); 
     if (p[i]) 
      Total += TenMB; else 
      break; 
    } 
    CString Msg; 
    Msg.Format("Allocated %0.3lfGB",Total/(1024.0*1024.0*1024.0)); 
    AfxMessageBox(Msg,MB_OK); 
} 

अंतिम संपादित मैं में कार्ड धारणा की एक डेक के रूप में सरणी के लिए पोइटा पद और विभिन्न टिप्पणियों को स्वीकार करने के लिए इसे निम्नलिखित, इसलिए नहीं कि मैं सीधे Deque वर्ग का उपयोग किया जाएगा का फैसला किया है, लेकिन अधिक टिप्पणियों का पालन किया। प्रति ब्लॉक तत्वों की एक निश्चित संख्या के आधार पर ओ (1) यादृच्छिक तत्व पहुंच के साथ लागू करने के लिए यह सरल होना चाहिए, जो मुझे चाहिए। प्रतिक्रिया के लिए सभी को धन्यवाद!

+3

मुझे आशा है कि उनमें से कोई भी "स्वाद" वीसी 6.0 –

+0

नहीं है जबकि मेरे पास अभी भी वीसी 6.0 है, और इसे कुछ चीजों के लिए उपयोग करें, रिलीज चरण के पास कहीं भी कहीं भी नहीं। अधिकतर वीएस 2008, कुछ वीएस2003, और कुछ ईवीसी ++ 4.0 यही कारण है कि मैं वीसी 6.0 भी बनाए रखता हूं। –

+0

एक 32-बिट विंडोज प्रोग्राम 2 जीबी से अधिक मेमोरी आवंटित कर सकता है, आप बस इसे एक ही समय में मैप नहीं कर सकते हैं। - http://blogs.msdn.com/oldnewthing/archive/2004/08/10/211890.aspx – Bill

उत्तर

11

क्या आपने std::deque का उपयोग करने का प्रयास किया है? std::vector के विपरीत, जो एक विशाल ढेर आवंटन का उपयोग करता है, deque आमतौर पर छोटे हिस्सों में आवंटित होता है, लेकिन फिर भी operator[] के माध्यम से निरंतर निरंतर समय अनुक्रमण प्रदान करता है।

+0

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

+0

मुझे नहीं पता कि यह आकार बदलने के लिए किस नीति का उपयोग करता है, लेकिन यह निश्चित रूप से 1 से अधिक है। मुझे संदेह है कि स्मृति अक्षमता 10% से अधिक होगी, और मैं उम्मीद करता हूं कि यह <5% हो। –

+0

std :: डेक पर पढ़ने के बाद, विशेष रूप से आवंटकों का उपयोग करने पर, मुझे कुछ भी नहीं मिला जो कहता है कि यह एक ही संगत ब्लॉक में सभी मेमोरी आवंटित करने का प्रयास नहीं करेगा। देखें http://www.cplusplus.com/reference/std/memory/allocator/ एक और तरीका रखें, मुझे यह सुझाव देने के लिए कुछ भी नहीं मिल रहा है कि एक डेक में 1 जीबी डेटा जोड़ने से हेपअलोक का उपयोग करने में सफल होने की संभावना अधिक है वहीं काम करें। क्या आपके पास यह सुझाव देने के लिए कोई संदर्भ है कि एक डेक डेटा की बहुत बड़ी मात्रा के लिए एकाधिक ढेर आवंटन का उपयोग करेगा, और यदि ऐसा है तो यह उन्हें कैसे खंडित करता है? –

3

अपने कार्यक्रम के दृष्टिकोण से आप हमेशा स्टार्टअप पर 2 जीबी उपलब्ध हैं, इससे कोई फर्क नहीं पड़ता कि सिस्टम में और क्या चल रहा है। मुझे विश्वास नहीं है कि विंडोज यह पता लगाने का एक तरीका प्रदान करता है कि क्या आपके पास डिस्क पर पिक्चर हो रहा है या नहीं। जहां तक ​​आप डेटा संरचनाएं जाते हैं, ऐसा लगता है कि आप एसटीएल में एक डेक लागू करने के समान कुछ बता रहे हैं।

+0

मुझे लगता है कि आपका मतलब डेक (http://www.cplusplus.com/reference/stl/deque/) है, नहीं विपंक्ति। – Bill

+0

ठीक है आप हैं। फिक्स्ड। – tloach

4

वास्तव में यह सरणी कितनी स्पैस है? यदि इसमें बड़ी मात्रा में खाली (अप्रयुक्त) जगह है, तो आप एक और दृष्टिकोण लेना चाहेंगे। answer to this question एक एसएलएल मानचित्र का सुझाव देता है।

यदि यह स्पैस नहीं है (जैसा कि टिप्पणियों में उल्लिखित है), विंडोज़ पर चलने के बाद से आप एक चीज देख सकते हैं जो memory-mapped file का उपयोग कर रहा है। हालांकि आपका ओएस 32-बिट हो सकता है, आपकी फाइल सिस्टम नहीं है। इसका मतलब यह है कि यद्यपि स्वैपिंग चल रही है, जो कि काफी धीमी गति से होने के लिए उत्तरदायी है अगर आप वास्तव में पूरे डर्न चीज को रैम में डाल सकते हैं।

इसके अलावा, आपको यह देखने के लिए कि क्या यह आपके लिए ठीक है या नहीं, आपको सिस्टम की रैम अधिकतम (32 जीबी विंडोज़ पर 3 जीबी) पर दस्तक देने पर विचार करना चाहिए। इससे आपको केवल $ 100 खर्च करना चाहिए, और आप इसके बारे में चिंता करने के लिए मानव-घंटे में उससे अधिक खर्च कर रहे हैं।

+0

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

+1

2 जीबी स्थापित होने के बाद! = 2 जीबी भौतिक राम उपलब्ध है। यदि आपके पास एक बड़ा मेमोरी ग्राफिक्स कार्ड है (यदि आप 3 डी काम कर रहे हैं तो यह एक अलग संभावना है) 4 जीबी स्थापित होने पर भी 2.5 जीबी से अधिक स्थापित नहीं हो सकता है। व्यक्तिगत रूप से सुनिश्चित करें कि आपके पास 4 + जीबी इंस्टॉल है और 64 बिट ओएस है। –

+1

@ ग्राहम - उसने पहले ही कहा है कि वह 32-बिट ओएस का उपयोग कर रहा था, और पूछ रहा था कि वह 64 बिट तक अपग्रेड करने से कम क्या कर सकता है। यही कारण है कि मैंने 3 जीबी तक जाने का सुझाव दिया। ऐसा कहा जा रहा है, मैं मानता हूं कि 64-बिट ओएस का उपयोग करना शायद एक अच्छा (और अपेक्षाकृत सस्ता) समाधान होगा। –

1

std :: डेक ठीक वही करता है जो आप वर्णन कर रहे हैं, लेकिन आम तौर पर ओएस पेज आकार की ग्रैन्युलरिटी (यानी, आवंटित किए गए भाग आमतौर पर 4 केबी होते हैं)।

यदि आप डेक के डिफ़ॉल्ट प्रदर्शन से नाखुश हैं, तो आप एक कस्टम आवंटक लिखने में सक्षम हो सकते हैं जो बड़े हिस्सों को पकड़ता है - यानी, एक समय में 1 एमबी या अधिक हो जाता है।

जैसा कि अन्य ने कहा है, आपकी प्रक्रिया का आभासी पता स्थान अन्य सभी प्रक्रियाओं से पूरी तरह से स्वतंत्र है, इसलिए आप 2 जीबी को संबोधित कर सकते हैं इससे कोई फर्क नहीं पड़ता कि आपके सिस्टम में और क्या चल रहा है। ओएस आपके मेमोरी पेज को डिस्क से/डिस्क से स्थापित कर देगा ताकि स्थापित मेमोरी की मात्रा और इसके लिए आने वाली सभी प्रक्रियाओं की बाधाओं को फिट किया जा सके। यह 4 केबी पृष्ठ आकार पर होगा, आपके भाग कितने बड़े हैं।

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

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