การจัดการหน่วยความจำที่ชาญฉลาดด้วยการดำเนินการเวลาคงที่?


18

ลองพิจารณาเซ็กเมนต์หน่วยความจำ (ขนาดที่สามารถเพิ่มหรือลดขนาดเช่นไฟล์เมื่อจำเป็น) ซึ่งคุณสามารถดำเนินการจัดสรรหน่วยความจำขั้นพื้นฐานที่เกี่ยวข้องกับการบล็อกขนาดคงที่สองแบบ:

  • จัดสรรหนึ่งบล็อก
  • การปลดบล็อกที่จัดสรรก่อนหน้านี้ซึ่งไม่ได้ใช้อีกต่อไป

นอกจากนี้ตามข้อกำหนดระบบการจัดการหน่วยความจำไม่ได้รับอนุญาตให้ย้ายไปรอบ ๆ บล็อกที่จัดสรรในปัจจุบัน: ดัชนี / ที่อยู่ของพวกเขาจะต้องไม่เปลี่ยนแปลง

อัลกอริทึมการจัดการหน่วยความจำที่ไร้เดียงสาที่สุดจะเพิ่มตัวนับทั่วโลก (ด้วยค่าเริ่มต้น 0) และใช้ค่าใหม่เป็นที่อยู่สำหรับการจัดสรรครั้งต่อไป อย่างไรก็ตามสิ่งนี้จะไม่อนุญาตให้ย่อส่วนเมื่อเหลือเพียงไม่กี่บล็อกที่ถูกจัดสรร

แนวทางที่ดีกว่า: รักษาตัวนับ แต่เก็บรักษารายการบล็อกที่ถูกจัดสรรคืน (ซึ่งสามารถทำได้ในเวลาคงที่) และใช้เป็นแหล่งสำหรับการจัดสรรใหม่ตราบเท่าที่ยังไม่ว่างเปล่า

อะไรต่อไป มีบางสิ่งที่ฉลาดที่สามารถทำได้ยังคงมีข้อ จำกัด ของการจัดสรรเวลาคงที่และการจัดสรรคืนซึ่งจะทำให้เซ็กเมนต์หน่วยความจำสั้นที่สุดเท่าที่จะทำได้?

(เป้าหมายสามารถติดตามบล็อกที่ไม่ได้รับการจัดสรรในปัจจุบันด้วยที่อยู่ที่เล็กที่สุด แต่ดูเหมือนจะไม่สามารถทำได้ในเวลาที่แน่นอน…)


การตรวจสอบรายชื่อจะไม่คงที่อีกต่อไปเนื่องจากรายการอาจเพิ่มขึ้นหรือลดลงเนื่องจากการจัดสรร / การจัดสรรบางส่วนทำได้ก่อนหน้านี้หรือไม่
Sim

@Sim ฉันคิดว่ามันเป็นรายการที่เชื่อมโยงและการดำเนินการจะเป็นเพราะคุณจะทำงานเฉพาะกับหัวหน้าเท่านั้น O(ยังไม่มีข้อความ)
svick

ฉันคิดว่า "วิธีการที่ดีกว่า" ของคุณจะใช้หน่วยความจำในปริมาณที่เหมาะสมอยู่แล้วนั่นคือจะไม่มีการจัดสรรหน่วยความจำเพิ่มเติมหากมีบล็อกว่าง คุณจินตนาการถึงวิธีการที่“ ฉลาด” จะปรับปรุงได้อย่างไร คุณหมายถึงควรจัดสรรให้ใกล้กับจุดเริ่มต้นเพื่อให้มีโอกาสที่ดีกว่าที่คุณจะลดขนาดกลุ่มหลังจากการจัดสรรคืนหรือไม่?
svick

@Sim: ขออภัยบางทีฉันควรจะใช้คำว่า stack (แต่ฉันคิดว่ามันอาจทำให้เกิดความสับสน) 'deallocate' เป็น push และ 'จัดสรร' เป็น pop หรือในกรณีที่ล้มเหลวก็แค่ถอยกลับไปที่เคาน์เตอร์ ทั้งสองเป็นเวลาคงที่
Stéphane Gimenez

คุณมีข้อ จำกัด ตามเวลาจริงหรือคุณพอใจกับเวลาคงที่ที่ถูกตัดจำหน่ายหรือไม่? คำตอบมีแนวโน้มที่จะแตกต่างกันมาก
Gilles 'หยุดความชั่วร้าย'

คำตอบ:


11

กับบล็อกขนาดคงที่สิ่งที่คุณได้อธิบายเป็นรายการฟรี นี่เป็นเทคนิคที่พบบ่อยมากโดยมีการบิดดังต่อไปนี้: รายการของบล็อกฟรีจะถูกเก็บไว้ในบล็อกฟรี ในรหัส C มันจะเป็นดังนี้:

static void *alloc_ptr = START_OF_BIG_SEGMENT;
static void *free_list_head = NULL;

static void *
allocate(void)
{
    void *x;

    if (free_list_head == NULL) {
        x = alloc_ptr;
        alloc_ptr = (char *)alloc_ptr + SIZE_OF_BLOCK;
    } else {
        x = free_list_head;
        free_list_head = *(void **)free_list_head;
    }
    return x;
}

static void
release(void *x)
{
    *(void **)x = free_list_head;
    free_list_head = x;
}

วิธีนี้ใช้ได้ดีตราบใดที่บล็อกที่จัดสรรไว้ทั้งหมดมีขนาดเท่ากันและขนาดนั้นเป็นขนาดหลายเท่าของตัวชี้เพื่อให้การจัดตำแหน่งนั้นถูกรักษาไว้ การจัดสรรและการจัดสรรคืนเป็นเวลาคงที่ (นั่นคือตามเวลาคงที่ในการเข้าถึงหน่วยความจำและการเพิ่มระดับพื้นฐาน - ในคอมพิวเตอร์ที่ทันสมัยการเข้าถึงหน่วยความจำอาจเกี่ยวข้องกับแคชคิดถึงและแม้แต่หน่วยความจำเสมือนดังนั้นการเข้าถึงดิสก์ อาจจะค่อนข้างใหญ่) ไม่มีโอเวอร์เฮดหน่วยความจำ (ไม่มีพอยน์เตอร์บล็อกต่อบล็อกหรืออะไรแบบนั้นบล็อกที่จัดสรรนั้นต่อเนื่องกัน) นอกจากนี้ตัวชี้การจัดสรรจะมาถึงจุดที่กำหนดเฉพาะในเวลาเดียวที่ต้องมีการจัดสรรบล็อกจำนวนมาก: เนื่องจากการจัดสรรต้องการใช้รายการฟรีตัวชี้การจัดสรรจะเพิ่มขึ้นเฉพาะเมื่อพื้นที่ด้านล่างตัวชี้ปัจจุบันเต็มนาฬิกา ในแง่ที่ว่า, เทคนิค.

ลดลงตัวชี้การจัดสรรหลังจากรีลีสอาจมีความซับซ้อนมากขึ้นเนื่องจากบล็อกฟรีสามารถระบุได้อย่างน่าเชื่อถือโดยทำตามรายการฟรีเท่านั้นซึ่งจะดำเนินการผ่านรายการเหล่านั้นตามลำดับที่คาดเดาไม่ได้ หากการลดขนาดเซกเมนต์ใหญ่เมื่อเป็นไปได้มีความสำคัญสำหรับคุณคุณอาจต้องการใช้เทคนิคทางเลือกพร้อมค่าใช้จ่ายที่มากขึ้น: ระหว่างบล็อกที่จัดสรรสองชุดคุณใส่ "หลุม" หลุมจะถูกเชื่อมโยงพร้อมกับรายการที่เชื่อมโยงเป็นสองเท่าตามลำดับหน่วยความจำ คุณต้องมีรูปแบบข้อมูลสำหรับรูที่คุณสามารถค้นหาที่อยู่เริ่มต้นของรูด้วยการรู้ว่ามันอยู่ตรงไหนและขนาดของรูถ้าคุณรู้ว่ารูเริ่มในหน่วยความจำ จากนั้นเมื่อคุณปล่อยบล็อกคุณจะสร้างหลุมที่คุณรวมกับหลุมถัดไปและก่อนหน้าสร้างใหม่ (ยังคงอยู่ในเวลาคงที่) รายการสั่งซื้อของหลุมทั้งหมด ค่าโสหุ้ยนั้นประมาณสองคำขนาดตัวชี้ต่อการจัดสรรบล็อก; แต่ในราคานั้นคุณสามารถตรวจจับการเกิดของ "หลุมสุดท้าย" ได้อย่างน่าเชื่อถือนั่นคือโอกาสที่จะลดขนาดเซ็กเมนต์ขนาดใหญ่

มีรูปแบบที่เป็นไปได้มากมาย กระดาษเบื้องต้นที่ดีคือการจัดสรรพื้นที่เก็บข้อมูลแบบไดนามิก: การสำรวจและการทบทวนที่สำคัญโดย Wilson และคณะ


4
คุณจะค้นหาหลุมที่ใกล้ที่สุดไปยังไซต์ deallocation ในเวลาคงที่ได้อย่างไร
Raphael

1
ในวิธีที่สองที่ฉันอธิบายหลุมเป็นส่วนหัว (คู่ของพอยน์เตอร์สำหรับรายการของหลุม) พร้อมกับพื้นที่สำหรับศูนย์บล็อกข้อมูลหนึ่งหรือมากกว่า ระหว่างบล็อกที่จัดสรรสองชุดจะมีรูอยู่เสมอแม้ว่าจะเป็นรูขนาดเล็กที่ประกอบด้วยส่วนหัวของรูเท่านั้น ดังนั้นการหาช่องที่ใกล้ที่สุดจึงเป็นเรื่องง่าย: พวกมันถูกต้องทั้งก่อนและหลังช่อง แน่นอนหลุมขนาดเล็กไม่ได้เป็นส่วนหนึ่งของรายการฟรี (รายการของหลุมที่มีสิทธิ์ได้รับการจัดสรร) อีกวิธีในการดูคือคุณเพิ่มส่วนหัวในทุกบล็อกและทุกรู (ไม่ใช่ไมโคร) (การจัดสรรภายใต้ Ms-Dos 16 บิตทำงานเช่นนั้น)
โทมัส Pornin

4

คำตอบนี้เป็นเรื่องเกี่ยวกับเทคนิคการจัดการหน่วยความจำทั่วไป ฉันพลาดที่คำถามถามเกี่ยวกับกรณีที่บล็อกทั้งหมดมีขนาดเท่ากัน (และอยู่ในแนวเดียวกัน)


กลยุทธ์พื้นฐานที่คุณควรจะรู้ว่าเป็นครั้งแรกที่พอดีต่อไปพอดีที่ดีที่สุดพอดีและระบบบัดดี้ ฉันเขียนบทสรุปสั้น ๆหนึ่งครั้งสำหรับหลักสูตรที่ฉันสอนฉันหวังว่าจะอ่านได้ ผมชี้ไปที่นั่นเพื่อสำรวจครบถ้วนสมบูรณ์อย่างเป็นธรรม

ในทางปฏิบัติคุณจะเห็นการเปลี่ยนแปลงต่าง ๆ ของกลยุทธ์พื้นฐานเหล่านี้ แต่สิ่งเหล่านี้ไม่ได้เป็นเวลาคงที่จริงๆ! ฉันไม่คิดว่าเป็นไปได้ในกรณีที่เลวร้ายที่สุดในขณะที่ใช้หน่วยความจำที่มีขอบเขต


น่าสนใจฉันต้องอ่านรายละเอียดนี้ อย่างไรก็ตามดูเหมือนว่าระบบเหล่านี้จะจัดการกับการจัดสรรขนาดที่ไม่คงที่โดยเฉพาะซึ่งไม่ใช่ปัญหาที่ฉันเผชิญ
Stéphane Gimenez

ขวา. ขออภัยฉันอ่านคำถามของคุณเร็วเกินไป
rgrig

O(LGn)

s / บล็อกว่าง / บล็อกฟรีที่เล็กที่สุดที่อยู่ที่น้อยที่สุด /
rgrig

2

คุณอาจต้องการดูการวิเคราะห์ค่าตัดจำหน่ายและโดยเฉพาะในอาร์เรย์แบบไดนามิก แม้ว่าการดำเนินการจะไม่ได้ดำเนินการอย่างแน่นอนในเวลาที่แน่นอนในทุกขั้นตอนในระยะยาวดูเหมือนว่าจะเป็นเช่นนั้น


2
และอาร์เรย์แบบไดนามิกจะช่วยจัดสรรหน่วยความจำได้อย่างไร
svick

คุณต้องการจัดสรรชิ้นเซลล์ที่ต่อเนื่องกันโดยใช้อัลกอริทึมแบบเดียวกันหรือไม่? ไฟล์ทั้งหมดของคุณจะเป็นรายการที่เชื่อมโยงกลุ่มที่ใหญ่กว่าและใหญ่กว่า
gallais
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.