2011-09-30 10 views
14

मैं एक टेक्स्ट फ़ाइल भेज रहा हूं - क्लाइंट-सर्वर टेक्स्ट को प्रत्येक 512 बाइट्स में पैकेट में ब्रेक अप करें, लेकिन कुछ पैकेट में प्रत्येक आकार को प्राप्त करते समय सर्वर के पक्ष में अधिकतम आकार से कम टेक्स्ट होता है जिसे मैं malloc() को कॉल कर रहा हूं एक स्ट्रिंग फिर से बनाना, क्या यह एक बुरा अभ्यास है? क्या एक काम करने वाला बफर रखना बेहतर है जो अधिकतम लंबाई के लिए फिट हो सकता है और इसके मूल्यों को प्रतिलिपि बना रहा है, प्रतिलिपि बना रहा है और ओवरराइट कर रहा है?कॉलिंग malloc() और मुक्त() को रखना कितना बुरा है?

ठीक @ n.m। यहां कोड है, यह अगर();

if(nbytes==2) { 
      packet_size=unpack_short(short_buf); 
      printf("packet size is %d\n",packet_size); 
      receive_packet(i,packet_size,&buffer); 
      printf("packet=%s\n",buffer); 
      free(buffer); 
} 
//and here is receive_packet() function 
int receive_packet(int fd,int p_len,char **string) { 
*string = (char *)malloc(p_len-2); // 2 bytes for saving the length  
char *i=*string; 
int temp; 
int total=0; 
int remaining=p_len-2; 
while(remaining>0) { 
    //printf("remaining=%d\n",remaining); 
    temp = recv(fd,*string,remaining,0); 
    total+=temp; 
    remaining=(p_len-2)-total; 
    (*string) += temp; 
} 
*string=i; 
return 0; 
} 
+0

कोड की एक पंक्ति हजारों टिप्पणियों के लायक है। –

+0

@ एनएम। मैंने मुख्य पोस्ट – cap10ibrahim

उत्तर

11

आपके उदाहरण में, आपके फ़ंक्शन में पहले से ही एक सिस्कल है, इसलिए malloc/free की सापेक्ष लागत लगभग अनजान होगी। मेरे सिस्टम पर, malloc/free "राउंड ट्रिप" औसत 300 चक्र, और सस्ता सिस्कोल (वर्तमान समय, पिड इत्यादि प्राप्त करना) कम से कम 2500 चक्रों की लागत है। recv की अपेक्षा आसानी से 10 गुना अधिक होने के लिए, इस मामले में आवंटन/मुक्त करने की लागत इस ऑपरेशन की कुल लागत का लगभग 1% होगी।

बेशक सटीक समय अलग-अलग होंगे, लेकिन परिमाण के मोटे आदेश सिस्टम में काफी आविष्कार होना चाहिए।मैं पूरी तरह से उपयोगकर्ता-स्थान वाले कार्यों को छोड़कर malloc/free को ऑप्टिमाइज़ेशन के रूप में हटाने पर भी विचार नहीं करना चाहूंगा। जहां गतिशील आवंटन के बिना जाने के लिए वास्तव में यह अधिक मूल्यवान है, वहां संचालन में है जो विफलता के मामलों में नहीं होना चाहिए - यहां मूल्य यह है कि और हार्डन को malloc विफल होने पर क्या करना है, इस बारे में चिंता न करें।

+0

मुझे यह विश्वास करना मुश्किल लगता है कि आपका मॉलोक/फ्री केवल 300 चक्र लेता है। क्या आप एक खंडित ढेर का उपयोग कर रहे हैं और मॉलॉक्स समेत जिन्हें ओएस से नई मेमोरी लाने की आवश्यकता है और इसे मुक्त करने से मुक्त है? –

+1

मैं समय मुक्त हूं (मॉलोक (1)); '(लिनक्स/ग्लिब/i686 पर,' rdtsc' के साथ मापने पर) जब इसे ओएस से नई मेमोरी मैप करने की आवश्यकता नहीं है, तो बस मौजूदा पूर्व-मुक्त स्मृति का पुन: उपयोग करें। यह लगभग हमेशा आम मामला होगा। ओएस से नई मेमोरी प्राप्त करने के लिए आपको समय के बारे में चिंता करने का एकमात्र समय रीयलटाइम प्रोग्रामिंग में है जहां आप ** प्रोग्राम के समग्र रनटाइम की बजाय किसी भी ऑपरेशन की ** सबसे खराब स्थिति ** विलंबता की परवाह करते हैं। –

+3

यह यादृच्छिक आकार के न्यूल और मॉलोक/मुफ्त यादृच्छिक आवंटन स्लॉट के लिए शुरू किए गए 10-100 आवंटन की सरणी का उपयोग करने के लिए एक बेहतर परीक्षण होगा। –

1

केवल परीक्षण द्वारा बताए गए के लिए है (;;) लूप के अंदर है। जब मैं सी में प्रोग्रामिंग करता हूं तो मैलोक से बचने के पक्ष में गलती करता है, क्योंकि अगर आप दुर्घटना से एक बनाते हैं तो मेमोरी लीक को ठीक करना मुश्किल हो सकता है।

7

कॉलिंग मॉलोक और मुफ्त के साथ ओवरहेड जुड़ा हुआ है। एक ब्लॉक को ढेर से आवंटित किया जाना चाहिए और उपयोग के रूप में चिह्नित किया जाना चाहिए, जब आप पुनरीक्षण मुक्त करते हैं। यह नहीं जानना कि आप किस ओएस या अनुपालन का उपयोग कर रहे हैं, यह सी लाइब्रेरी में या ओएस मेमोरी मैनेजमेंट स्तर पर हो सकता है। चूंकि आप बहुत सारे मॉलॉक्स कर रहे हैं और मुक्त हैं, इसलिए आप अपने ढेर को अलग-अलग टुकड़े कर सकते हैं जहां आपके पास कहीं और मॉलोक करने के लिए पर्याप्त संगत मुक्त स्मृति नहीं हो सकती है। यदि आप केवल एक बफर आवंटित कर सकते हैं और इसका पुन: उपयोग कर सकते हैं, तो आमतौर पर तेज़ होने जा रहा है और ढेर विखंडन का कम खतरा होता है।

+2

पर कोड जोड़ा है यदि वह एक निश्चित आकार के ब्लॉक को आवंटित और मुक्त कर रहा है, तो वह लगभग निश्चित रूप से कुछ भी खंडित नहीं कर रहा है। (इसका मतलब यह नहीं है कि कोई ओवरहेड नहीं है ... लेकिन विखंडन शायद इस मामले में इसका कारण नहीं बनता है।) – Nemo

+0

मान लीजिए कि कार्यक्रम में ढेर से स्मृति आवंटित नहीं किया जा रहा है, और यह एक धागा है, मैं सहमत हूं। यह शायद हर बार स्मृति का एक ही ब्लॉक लौटाया जा रहा है। हालांकि, हमें नहीं पता कि कार्यक्रम में ढेर से आवंटित किया जा रहा है, या यह विशेष ढेर प्रबंधक कैसे कार्यान्वित किया जाता है। – user957902

1

कॉलिंग कई malloc/मुक्त वास्तव में,, (किसी भी शामिल लीक बिना) अपनी प्रक्रिया द्वारा प्रयुक्त स्मृति में वृद्धि करता है, तो आकार malloc के लिए पारित कर दिया चर रहा है कर सकते हैं इस सवाल से सिद्ध है:

C program memory usage - more memory reported than allocated

तो एकल बफर दृष्टिकोण शायद सबसे अच्छा है।

3

मुझे पता चला है कि malloc, realloc और free बहुत महंगा हैं। यदि आप मॉलोक से बच सकते हैं तो आपके द्वारा पहले से प्राप्त मेमोरी का पुन: उपयोग करना बेहतर होगा।

संपादित करें:
ऐसा लगता है कि मैं गलत हूं कि मैलोक कितना महंगा है। लिनक्स पर GNU सी लाइब्रेरी संस्करण 2.14 के साथ कुछ समय परीक्षणों से पता चलता है कि एक परीक्षण है कि 100,000 बार और आबंटित करता लूप और 163,840 बाइट्स 1 से यादृच्छिक आकारों के साथ 512 स्लॉट को मुक्त कर देते के लिए:

tsc average loop = 408 
tsc of longest loop = 294350 

तो 408 malloc या कर चक्र बर्बाद new एक तंग आंतरिक लूप में करने के लिए एक मूर्ख बात होगी। इसके अलावा इसके बारे में चिंता करने से परेशान नहीं है।

+0

आपकी प्रतिक्रिया के लिए धन्यवाद – cap10ibrahim

1

दो समाधानों के प्रदर्शन को मापें। या तो प्रोफाइलिंग को मापने या मापने के द्वारा। कुछ के लिए कुछ भी कहना असंभव है।

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