4.19. หน่วยความจำแบบพูล¶
กล้องที่เก็บเฟรมความละเอียดสูงสุดสามเฟรมไว้ในพูลบัฟเฟอร์เฟรม พร้อมบัฟเฟอร์พรีวิวแยกต่างหากที่ทำงานควบคู่กัน และยังมีพื้นที่เหลือสำหรับสคริปต์ Python และออบเจ็กต์ต่าง ๆ นั้นต้องจัดการหน่วยความจำมากกว่าที่บล็อก RAM เดียวบน MCU จะจัดหาได้ MicroPython รองรับทุกอย่างโดยกระจายข้ามหน่วยความจำประเภทต่าง ๆ ที่แตกต่างกันที่ MCU มีให้ และนำการจัดสรรแต่ละประเภทไปยังหน่วยความจำที่เหมาะสม
4.19.1. ประเภทของหน่วยความจำ¶
MCU ของ OpenMV Cam รุ่นใหม่มีหน่วยความจำสี่ประเภทที่แตกต่างกัน ประเภทแรกไม่ปรากฏต่อแอปพลิเคชัน ส่วนอีกสามประเภทเป็นพูลที่การจัดสรรจะมาจาก
แคชข้อมูลของ CPU -- พื้นที่หน่วยความจำขนาดเล็กที่รวดเร็วมากซึ่งอยู่ระหว่าง CPU และ RAM ส่วนที่เหลือ เมื่อ CPU อ่านหรือเขียนค่าจากหน่วยความจำหลัก แคชจะเก็บสำเนาไว้โดยอัตโนมัติ ทำให้การเข้าถึงข้อมูลเดิมซ้ำ ๆ อยู่ในแคชโดยไม่ต้องเสียเวลาออกไปยังหน่วยความจำที่ช้ากว่า แคชไม่ใช่พูลที่การจัดสรรมาจาก มันโปร่งใสต่อแอปพลิเคชัน -- มันแค่ทำให้ RAM ส่วนที่เหลือรู้สึกเร็วกว่าเวลาแฝงจริงในทางปฏิบัติ จนกว่าชุดข้อมูลที่ใช้งานจะมีขนาดเกินแคช
หน่วยความจำโปรเซสเซอร์แบบเชื่อมต่อแน่น -- บล็อก RAM ขนาดเล็กที่ต่อตรงกับ CPU โดยไม่มีบัสคั่น การเข้าถึงแบบ Single-cycle ไม่มีการพลาดแคช ไม่มีการรอ การจัดสรรที่ต้องการหน่วยความจำที่เร็วที่สุดอย่างแท้จริง -- ซึ่งทุกรอบของเวลาแฝงสำคัญ -- มาจากพูลนี้
หน่วยความจำ on-chip ที่รวดเร็ว -- RAM หลายร้อยกิโลไบต์ถึงประมาณหนึ่งเมกาไบต์ที่สร้างไว้ในแพ็กเกจ MCU เวลาแฝงต่ำ แบนด์วิดท์สูง แต่จำกัดขนาด MicroPython heap อาศัยอยู่ที่นี่เพื่อให้การเข้าถึงออบเจ็กต์ Python รวดเร็ว บัฟเฟอร์การทำงานขนาดเล็กที่ CPU ใช้งานบ่อยจะใช้พูลร่วมกัน
หน่วยความจำ bulk ที่ช้ากว่า -- บนบอร์ดที่จับคู่ MCU กับชิปหน่วยความจำภายนอก RAM นอกชิปหลายสิบเมกาไบต์ที่เข้าถึงผ่านบัสภายนอก มีขนาดใหญ่กว่ามาก แต่การเข้าถึงแต่ละครั้งใช้เวลานานกว่าหน่วยความจำ on-chip แคชข้อมูลซ่อนต้นทุนส่วนใหญ่สำหรับชุดข้อมูลที่สามารถเก็บได้ และช่องว่างจะปรากฏในการดำเนินการที่กวาดข้อมูลขนาดใหญ่เกินกว่าจะแคชได้ ใช้สำหรับการจัดสรรที่ต้องมีขนาดใหญ่และที่ CPU ยอมรับความเร็วที่ช้ากว่าได้ -- ที่สำคัญที่สุดคือพูลบัฟเฟอร์เฟรม
บอร์ดในตระกูลนี้มีหลากหลาย: บางบอร์ดมีเฉพาะ RAM on-chip บางบอร์ดจับคู่ RAM on-chip กับบล็อกภายนอกที่ใหญ่กว่ามาก หน่วยความจำที่จัดสรรได้สามประเภทแต่ละประเภทถือเป็นหน่วยความจำแบบพูล -- ก้อนที่การจัดสรรมาจาก -- และมีป้ายกำกับเพื่อให้คำขอแต่ละรายการสามารถขอประเภทหน่วยความจำที่ต้องการได้จริง
4.19.2. บัฟเฟอร์เฟรมหลัก¶
บัฟเฟอร์เฟรมที่รองรับ snapshot() ไม่ได้ขอหน่วยความจำที่เร็ว แต่ขอหน่วยความจำที่เพียงพอ -- ไม่มากไปกว่านั้น ทำให้มันอยู่ในพูลที่ใหญ่ที่สุด ดังนั้นบนบอร์ดที่มีทั้งหน่วยความจำ on-chip และภายนอก บัฟเฟอร์เฟรมจะอยู่ในบล็อกภายนอก
บัฟเฟอร์เฟรมแบบ triple-buffered ที่ความละเอียดเต็มมีขนาดใหญ่เกินกว่าจะใส่ในพูล on-chip ที่รวดเร็วในส่วนใหญ่ พูลที่ใหญ่กว่าเป็นพูลเดียวที่สามารถรองรับได้ แคชข้อมูลของ CPU ซ่อนต้นทุนการเข้าถึงส่วนใหญ่เมื่อแอปพลิเคชันประมวลผลภาพ และเอนจิน DMA ที่เติมบัฟเฟอร์เฟรมจาก sensor ก็สามารถรับมือกับอัตราข้อมูลของ sensor ได้ในทุกกรณี
ขนาดที่แน่นอนที่บัฟเฟอร์เฟรมใช้ถูกเลือกจาก pixformat(), framesize(), และจำนวน framebuffers() ในปัจจุบัน ขนาดจะเพิ่มหรือลดทุกครั้งที่มีการเปลี่ยนแปลงอย่างใดอย่างหนึ่ง
4.19.3. บัฟเฟอร์เฟรม sensor รอง¶
อินสแตนซ์ CSI ที่สองได้รับบัฟเฟอร์เฟรมของตัวเอง จัดสรรจากพูลเดียวกับที่หลักใช้ พูลเป็นทรัพยากรร่วม แต่บัฟเฟอร์เป็นอิสระจากกัน รอยเท้าหน่วยความจำของ sensor รองมักเล็กกว่าหลักมาก เนื่องจาก sensor รองทำงานที่ความละเอียดต่ำกว่า ดังนั้นหน่วยความจำเพิ่มเติมที่บัฟเฟอร์เฟรมที่สองใช้จึงเป็นเพียงส่วนน้อยของหลัก
4.19.4. บัฟเฟอร์เฟรม stream¶
บัฟเฟอร์ image preview เป็นข้อยกเว้น มันไม่ได้จัดสรรจากพูลใดในรันไทม์ มันเป็นพื้นที่ที่ตรึงไว้สำรองไว้ตั้งแต่ build time พร้อมที่อยู่ที่ทราบและขนาดที่ทราบ สิ่งนี้ทำให้เส้นทางพรีวิวไม่รบกวนการจัดสรรอื่น ๆ -- พื้นที่มีอยู่ตั้งแต่บูตและไม่เคยเปลี่ยนที่
4.19.5. MicroPython heap¶
ออบเจ็กต์ Python -- ตัวแปร รายการ พจนานุกรม อินสแตนซ์คลาส wrapper Image ที่การเรียก snapshot() คืนค่า ทุก string และ tuple ที่แอปพลิเคชันสร้าง -- อาศัยอยู่บนMicroPython garbage-collected heap ซึ่งแยกต่างหากจากพูลหน่วยความจำของกล้อง GC heap เป็นพื้นที่หน่วยความจำที่ MicroPython จัดการเอง: โค้ด Python จัดสรรจากมันโดยปริยายทุกครั้งที่มีการสร้างออบเจ็กต์ และ MicroPython จะสแกน heap เป็นระยะและเรียกคืนพื้นที่ที่ออบเจ็กต์ที่แอปพลิเคชันไม่ได้อ้างอิงอีกต่อไปใช้ ดังนั้นแอปพลิเคชันไม่ต้องเพิ่มหน่วยความจำคืนเอง
พื้นที่เฉพาะถูกแยกไว้สำหรับ GC heap ตั้งแต่บูต โดยปกติวางไว้ในหน่วยความจำ on-chip ที่รวดเร็วเพื่อให้การเข้าถึง Python รวดเร็ว พร้อม overflow ทางเลือกไปยังบล็อกภายนอกที่ใหญ่กว่าบนบอร์ดที่ต้องการพื้นที่เพิ่มเติมสำหรับโครงสร้างข้อมูลขนาดใหญ่
Image ที่ snapshot() คืนค่าเป็น wrapper object ขนาดเล็กบน GC heap ข้อมูลพิกเซลพื้นฐานอยู่ในบัฟเฟอร์เฟรมในพูลหนึ่งของกล้อง ทั้งสองไม่แข่งขันกันสำหรับหน่วยความจำเดียวกัน
4.19.6. รวมกันทั้งหมด¶
การนำการจัดสรรแต่ละประเภทไปยังพูลที่ถูกต้อง -- บัฟเฟอร์ขนาดใหญ่ไปยังพูลที่ใหญ่กว่าซึ่งสามารถรองรับได้ ข้อมูลที่ไวต่อเวลาแฝงไปยังพูลที่เร็วกว่า Python heap ไปยังพื้นที่ของตัวเอง พรีวิวไปยังช่องสำรองของมัน -- ทำให้สามารถรันไปป์ไลน์การจับภาพความละเอียดสูง ช่องพรีวิว และสคริปต์ Python ที่ไม่ธรรมดาควบคู่กันบน MCU ที่มีหน่วยความจำ on-chip ที่รวดเร็วรวมเพียงไม่กี่เมกาไบต์