2013-10-30 3 views
5

मैं वर्तमान में लागू करने के लिए Buddy Allocator कंप्यूटर प्रोग्रामिंग खंड की कला में वर्णित कोशिश कर रहा हूँ: अपनी इसी 1 है, जो डेटा की एक दिए गए ब्लॉक और का पता करने में एक महत्वपूर्ण अपरिवर्तनीय का लाभ लेता है साथी। गणना इस प्रकार है ...बडी आबंटन एल्गोरिथ्म - शुरुआत ढेर पता

BUDDY(X): 

X + 2^i if x mod 2^i+1 = 0 
X - 2^i if x mod 2^i-1 = 0 

Where X is the address of the block; i is the current order 

क्या साथी प्रणाली बनाता प्रदर्शन इतनी अच्छी तरह से (है कि इस गणना के साथी का पता लगाने के लिए, बस ith आदेश बिट के एक फ्लिप साथ किया जा सकता है xor'ing के माध्यम से यह 1 < < i) के साथ। यदि बाएं ब्लॉक पते दिए गए हैं, तो यह सही ब्लॉक लौटाएगा। यदि सही ब्लॉक दिया गया है, तो यह बाएं ब्लॉक को वापस कर देगा।

हालांकि, यह विधि मानती है कि ढेर 0 पते पर शुरू होता है। यदि ढेर उन पतों के साथ शुरू होता है जिनके पास मेरे आदेश की सीमा के भीतर बिट्स हैं, तो उपर्युक्त गणना करने से आपको सही पता नहीं मिलेगा उसका दोस्त

इसलिए, बस, इस गणना को सामान्यीकृत करने का कोई तरीका है ताकि इसे किसी भी प्रारंभिक ढेर पते पर किया जा सके? मान लें कि अधिकतम आदेश के लिए बाध्य है। आईई * यदि अधिकतम आदेश 18 वर्ष है, तो हम 18 के आदेश से अधिक या उसके बराबर गणना करने की कोशिश नहीं करेंगे, इसलिए आपको अपने दोस्त को खोजने की आवश्यकता नहीं है।

इस पर किसी भी मदद या सुझाव की बहुत सराहना की!

+0

क्यों कोई अन्य फ़ंक्शन नहीं बनाते, AnyBuddy (X, startPoint) = Buddy (X-startPoint) + startPoint? – ElKamina

+0

@ElKamina इसके बजाय यदि आपके पास कोई जवाब है तो उसे उत्तर दें। – this

+0

स्वयं। मैंने जो पोस्ट किया वह काफी जवाब था। वैसे भी, ट्रिस्टन ने पहले से ही एक और अधिक पठनीय प्रारूप में प्रस्तुत किया है। – ElKamina

उत्तर

3

वाह, कट्टर। Knuth पढ़ने के लिए Kudos!

वैसे भी, मैं इस बिंदु को याद कर रहा हूं, लेकिन किसी बिंदु पर आप ओएस से स्मृति प्रणाली के एक संगत खंड का अनुरोध कर रहे हैं (दोस्ताना)। तो क्या आप बस शुरुआती पता नहीं रख सकते थे (आपको इसे बाद में free() की आवश्यकता है), और आपके द्वारा उपयोग किए जाने वाले पते को शून्य-आधारित होने के लिए ऑफ़सेट का उपयोग करें? यानी इस तरह कुछ:

uint8_t* start_addr = malloc(SIZE_IN_BYTES); 

uint8_t* buddy(uint8_t* real_x) { 
    uint8_t *x = real_x - start_addr; 
    // do buddy bit-flipping on "x" 
    return x + start_addr; 
} 
+0

मैं साझा स्मृति के लिए दोस्त आवंटक को एक बार लागू करता हूं और वास्तव में इस दृष्टिकोण का उपयोग करता हूं :) – Lazin

+0

इसके बारे में एक और सवाल, क्या नया पता स्थान 0x4 पर शुरू होना ठीक है? मुझे नि: शुल्क पॉइंटर्स के लिए 0x0 आरक्षित करने की आवश्यकता है ताकि यह बताने के लिए कि मैं अपनी सूची सूची के लिए सूची के अंत में हूं। – jab

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