1 पॉइंट द्वारा GN⁺ 2025-04-24 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • Go भाषा में undefined behavior लगभग नहीं के बराबर है, और इसकी सरल GC (garbage collection) semantics है
  • Go में manual memory management संभव है, और इसे GC के साथ मिलकर किया जा सकता है
  • Arena एक data structure है जो समान lifetime वाली memory को कुशलता से allocate करता है, और यह लेख बताता है कि Go में इसे कैसे implement किया जाए
  • Mark and Sweep algorithm के ज़रिए GC memory को कैसे manage करता है, यह समझाया गया है
  • Arena का उपयोग करके memory allocation performance बेहतर की जा सकती है, और यह कई optimizations के माध्यम से संभव है
  • write barrier हटाना, memory reuse, chunk pooling आदि के ज़रिए performance बढ़ाने और GC का बोझ कम करने की कोशिश की गई है
  • realloc implementation, Arena reuse और initialization (Reset) जैसी सुविधाओं के माध्यम से बड़े पैमाने की memory processing के लिए सुरक्षित और तेज़ patterns पेश किए गए हैं

Go में Arena-आधारित manual memory allocation का अवलोकन

  • Go एक सुरक्षित भाषा है, क्योंकि इसमें स्पष्ट GC behavior और लगभग न के बराबर undefined behavior है
  • unsafe package का उपयोग करके GC की internal implementation के अनुरूप memory को सीधे नियंत्रित किया जा सकता है
  • यह लेख बताता है कि Go में GC के साथ सहयोग करने वाला Arena structure-आधारित memory allocator कैसे बनाया जा सकता है

Arena की परिभाषा और ज़रूरत

  • Arena एक ऐसी structure है जो एक ही lifetime वाले objects को कुशलता से allocate करने के लिए बनाई जाती है
  • जहाँ सामान्य append exponentially array को expand करता है, वहीं Arena नया block जोड़कर pointer उपलब्ध कराता है
  • standard interface इस प्रकार है:
    • Alloc(size, align uintptr) unsafe.Pointer

Pointer और GC कैसे काम करते हैं

  • GC memory को track (mark) और reclaim (sweep) करने के तरीके से काम करता है
  • precise GC के लिए pointer bits नाम का metadata इस्तेमाल होता है, जो pointer locations की जानकारी देता है
  • अगर Arena में pointers को गलत तरीके से संभाला जाए, तो GC pointers को track नहीं कर पाएगा, जिससे use-after-free error हो सकती है

Arena डिज़ाइन करने का तरीका

  • Arena structure में ये fields होते हैं:
    • next, left, cap, chunks
  • सभी allocations को 8-byte alignment के साथ handle किया जाता है, और जगह कम पड़ने पर nextPow2 से नया chunk बनाया जाता है
  • chunk को []uintptr के बजाय struct { A [N]uintptr; P *Arena } type के रूप में allocate किया जाता है, ताकि GC Arena को track कर सके

Arena में pointer safety सुनिश्चित करने के तरीके

  • जब केवल Arena के भीतर allocate किए गए pointers का उपयोग किया जाता है, तो GC पूरे Arena को जीवित रखता है
  • pointer को Arena की ओर reference देने से पूरा Arena GC में survive करने की गारंटी पाता है
  • Arena की allocation method यह काम करती है:
    • allocChunk() में Arena pointer को chunk के अंत में store किया जाता है

Performance benchmark के नतीजे

  • सामान्य new की तुलना में Arena allocation औसतन 2~4 गुना या उससे अधिक performance improvement दिखाती है
  • GC load बहुत ज़्यादा होने पर भी Arena तरीका अधिकतम 2 गुना से अधिक बेहतर performance दिखाता है
  • write barrier हटाने, uintptr के उपयोग जैसी optimizations से छोटे allocations में अधिकतम 20% performance improvement मिलता है

Chunk reuse और heap हटाने की रणनीति

  • sync.Pool का उपयोग करके chunks को reuse किया जा सकता है
  • runtime.SetFinalizer() के माध्यम से Arena के समाप्त होने पर chunks को pool में वापस भेजा जा सकता है
  • छोटे allocations में performance बहुत बेहतर होती है, लेकिन बड़े allocations में यह new से धीमा हो सकता है

Arena initialization और reuse सुविधा

  • Reset() method से Arena को शुरुआती स्थिति में वापस लाया जा सकता है
  • यह काफ़ी risky है, लेकिन memory को दोबारा allocate किए बिना उसी structure को reuse किया जा सकता है
  • reuse के दौरान भी chunk reuse होने से performance में बड़ा सुधार मिलता है

Realloc सुविधा का implementation

  • Arena में realloc सुविधा implement करके सबसे हाल की allocation को dynamically expand किया जा सकता है
  • यदि यह संभव न हो, तो नई memory allocate करके copy किया जाता है

निष्कर्ष और पूरा code उपलब्ध

  • Go के GC mechanism को गहराई से समझकर, उसकी internal implementation के आधार पर Arena-आधारित memory manager पूरा किया गया है
  • यह structure safety और performance दोनों देती है, और सही तरीके से इस्तेमाल करने पर बड़े data structures को संभालने में बहुत उपयोगी है
  • पूरे implementation code में Arena struct और New, Alloc, Reset, allocChunk, finalize आदि शामिल हैं

1 टिप्पणियां

 
GN⁺ 2025-04-24
Hacker News टिप्पणियाँ
  • यह लेख पढ़ने में मज़ेदार है

    • अगर आपको यह लेख पसंद आया हो या आप Go में memory allocation पर बेहतर control चाहते हों, तो मैंने जो package लिखा है उसे देखें
    • feedback मिले या दूसरे लोग इसका उपयोग करें, यह अच्छा लगेगा
    • यह package runtime से अलग अपनी खुद की memory allocate करता है, इसलिए GC को पूरी तरह bypass करता है
    • allocation के समय pointer type की अनुमति नहीं देता, लेकिन उसी तरह की functionality देने वाले Reference[T] type से इसकी भरपाई करता है
    • memory free करना manually होता है, इसलिए garbage collection पर निर्भर नहीं रहा जा सकता
    • Go में ऐसे custom allocators आम तौर पर arenas की ओर उन्मुख होते हैं, जो उन allocation groups को support करते हैं जिन्हें साथ में बनाया और नष्ट किया जाता है
    • लेकिन offheap package का लक्ष्य बड़े, लंबे समय तक रहने वाले data structures बनाना है ताकि garbage collection की लागत शून्य हो जाए
    • जैसे बड़े in-memory cache या database
  • हाल ही में Go में performance tuning करते समय, performance को अधिकतम करने के लिए मैंने बहुत मिलती-जुलती arena design का उपयोग किया

    • unsafe pointers की जगह byte slices को buf और chunk के रूप में उपयोग किया
    • ऐसा करके देखा, लेकिन यह तेज़ नहीं था और बहुत अधिक जटिल था
    • 100% निश्चित होने से पहले मुझे दोबारा जाँच करनी चाहिए
  • कुछ आसान सुधार

    • अगर छोटी slice से शुरुआत हो और कुछ payload बड़ी मात्रा में जोड़े जाएँ, तो built-in append को कॉल करने से पहले cap को अधिक आक्रामक रूप से बढ़ाने वाला अपना append लिखें
    • unsafe.String byte slice से string को बिना allocation के पास करने में उपयोगी है
    • warnings को ध्यान से पढ़ना और समझना चाहिए कि आप क्या कर रहे हैं
  • विषय से हटकर, लेकिन बगल में दिया गया minimap मुझे पसंद आया

    • लंबे technical articles में इधर-उधर जाकर पढ़ने या पहले पढ़ी चीज़ों को फिर से संदर्भित करने में यह उपयोगी है
    • सोच रहा हूँ कि इसे अपनी site में कैसे जोड़ सकता हूँ
    • वाकई शानदार है
  • जो लोग लंबा लेख पढ़ने में हिचकते हैं, उनके लिए सारांश

    • OP ने Go में unsafe का उपयोग करके allocator के काम को तेज़ करने के लिए एक arena allocator बनाया
    • यह खास तौर पर तब उपयोगी है जब बहुत-सी चीज़ें साथ में allocate और destroy की जाती हैं
    • मुख्य समस्या यह है कि Go का GC ठीक से काम करने के लिए data layout, खासकर pointer कहाँ हैं, यह जानना चाहता है
    • अगर unsafe.Pointer से raw bytes allocate किए जाएँ, तो GC arena के भीतर pointers को ठीक से नहीं देख पाता और गलती से उन्हें free कर सकता है
    • लेकिन इसे इस तरह काम करने लायक बनाने के लिए कि pointers जब तक उसी arena की दूसरी चीज़ों की ओर इशारा करें तब तक सब सही रहे, अगर arena का कोई हिस्सा अभी भी referenced है तो पूरा arena बनाए रखा जाता है
    • (1) एक slice (chunks) रखी जाती है जो उन सभी बड़े memory blocks की ओर इशारा करती है जो arena ने system से लिए हैं
    • (2) और reflect.StructOf का उपयोग करके एक नया type बनाया जाता है, ताकि इन blocks में अतिरिक्त pointer fields शामिल हों
    • इसलिए अगर GC को chunks की ओर pointer मिल जाता है, तो उसे back pointers भी मिल जाते हैं, जिससे arena को live चिह्नित किया जाता है और chunk slice बनी रहती है
    • इसके बाद विभिन्न internal checks और write barriers को हटाने के लिए दिलचस्प optimization techniques पेश की जाती हैं
  • संबंधित: standard library में "memory regions" जोड़ने पर चर्चा

    • पिछला arena proposal
  • दिलचस्प बात है

    • जिज्ञासा है कि Go में off-heap या arena-style allocators बनाने वाले लोग memory safety और GC interaction को आम तौर पर कैसे test या benchmark करते हैं
  • Go ecosystem को टूटने से बचाने को प्राथमिकता देता है

    • इसका मतलब है कि Hyrum's Law runtime के कुछ खास observable behavior की रक्षा करेगा, यह मान लेना संभव हो जाता है
    • अगर यह दावा सही है, तो Go एक language के रूप में विकास की dead end पर है
    • इस स्थिति में मुझे यक़ीन नहीं कि Go दिलचस्प है
  • एक छोटी meta note

    • यह लेख वास्तव में बहुत लंबा है, इसलिए background की details पढ़ने का समय नहीं है
    • उदाहरण के लिए, "Mark and Sweep" section ही मेरे laptop screen पर 4 पेज से अधिक घेर लेता है
    • वह section लेख शुरू होने के 5 पेज बाद शुरू होता है
    • सोचता हूँ कि क्या AI ने section लिखने में मदद की, जिसकी वजह से यह ज़रूरत से ज़्यादा व्यापक हो गया
    • content generation आसान है, लेकिन महत्वपूर्ण हिस्सों को बनाए रखने के लिए editorial decisions नहीं लिए गए
    • मुझे arena allocator वाला हिस्सा ही जानना है, garbage collection पर tutorial नहीं चाहिए