วิธีการเข้าถึงประสิทธิภาพการอ่านพร้อมกันที่ดีจากดิสก์ใน Windows
เมื่อทำงานกับไฟล์ขนาดใหญ่ในสภาพแวดล้อมแบบมัลติเทรด การเข้าถึงประสิทธิภาพการอ่านจากดิสก์ที่เหมาะสมสามารถก่อให้เกิดความท้าทายที่สำคัญ ในสถานการณ์ที่คุณมีหลายเธรดพยายามอ่านจากไฟล์ต่างๆ พร้อมกัน คุณอาจพบว่าประสิทธิภาพลดลงเนื่องจากนโยบายการจัดตารางดิสก์ของระบบปฏิบัติการ โพสต์นี้จะพูดถึงปัญหาทั่วไปที่พบและนำเสนอวิธีการเพื่อเพิ่มประสิทธิภาพการอ่านดิสก์ใน Windows
ปัญหา: ข้อจำกัดในประสิทธิภาพการอ่านพร้อมกัน
ลองจินตนาการว่าคุณมีไฟล์ขนาดใหญ่สองไฟล์ ขนาดประมาณ 2 GiB และเธรดแยกกันสองเธรดพยายามอ่านไฟล์เหล่านี้พร้อมกัน แทนที่จะได้รับประสิทธิภาพที่ดีกว่า คุณพบว่าเธรดทั้งสองมีประสิทธิภาพต่ำและได้ผ่านput รวมเพียง 2-3 MiB/sec สรุปสถานการณ์ได้ดังนี้:
- การตั้งค่า: เธรดสองเธรด อ่านไฟล์ละหนึ่งไฟล์
- การสังเกต: ผ่านput รวมต่ำเมื่อเธรดทั้งสองใช้งานอยู่ (~2-3 MiB/sec) เมื่อเปรียบเทียบกับประสิทธิภาพที่ดีกว่าเมื่อมีเธรดเดียว (~45 MiB/sec)
- สาเหตุที่น่าสงสัย: พฤติกรรมการค้นหาดิสก์ที่กระทบโดย Windows disk scheduler ซึ่งนำไปสู่รูปแบบการอ่านที่ไม่มีประสิทธิภาพ
เข้าใจการจัดตารางดิสก์ใน Windows
ก่อนที่เราจะดำดิ่งสู่ทางแก้ไข มันสำคัญมากที่จะต้องเข้าใจว่า Windows จัดการคำขอ I/O ดิสก์อย่างไร โดยประวัติศาสตร์แล้ว Windows ใช้คิว FIFO (First In, First Out) สำหรับคำขอดิสก์ ซึ่งคำขอถูกแบ่งเป็นบล็อกขนาด 64 KB ผลลัพธ์ที่ได้คือ:
- การค้นหาดิสก์บ่อยครั้ง: เมื่อเธรดสองเธรดอ่านพร้อมกัน คำขอของพวกเขาขัดแย้งกัน ส่งผลให้เกิดการค้นหาย้อนกลับไปย้อนกลับมาบนดิสก์อยู่ตลอดเวลา
- ไม่มีความยืดหยุ่น: ก่อนหน้านี้ Windows Vista ผู้พัฒนามีน้อยมากที่สามารถปรับเปลี่ยนการจัดการคำขอข้อมูล
อย่างไรก็ตาม การนำ Windows Vista มาใช้ได้มีการนำอัลกอริธึมการจัดตารางดิสก์ที่ซับซ้อนขึ้นมาใช้ ทำให้สามารถบริหารจัดการการดำเนินการ I/O พร้อมกันได้ดียิ่งขึ้น ซึ่งทำให้เกิดคำถามว่า เราจะทำอะไรเพื่อเพิ่มประสิทธิภาพการอ่านในระบบที่ยังไม่เป็น Vista หรือแม้แต่ในรุ่นที่ใหม่กว่าหากยังคงมีปัญหาอยู่?
วิธีการที่เสนอเพื่อปรับปรุงประสิทธิภาพการอ่านพร้อมกัน
-
นโยบายการเข้าถึงดิสก์ที่สร้างเอง: เนื่องจากคุณไม่สามารถปรับเปลี่ยนนโยบายการจัดตารางในเวอร์ชัน Windows ที่เก่ากว่า ให้พิจารณาสร้างวิธีการของคุณเองเพื่อจัดการการเข้าถึงดิสก์ในเธรดของคุณ
- ตัวอย่างการดำเนินการนโยบาย:
if (THREAD_A is reading from disk) { wait for THREAD_A to stop reading or wait for X ms } read for X ms (or Y MB) stop reading and check the status of THREAD_A again
นโยบายนี้แนะนำกลไกการรอซึ่งเธรดจะเข้าถึงดิสก์ได้เฉพาะเมื่อเธรดอื่นไม่กำลังอ่านอยู่ ซึ่งช่วยลดปัญหาการค้นหา
- ตัวอย่างการดำเนินการนโยบาย:
-
ใช้ Primitive การซิงค์: ใช้ semaphore หรือ mutex เพื่อควบคุมการเข้าถึงดิสก์ มั่นใจได้ว่ามีเพียงเธรดเดียวที่อ่านในแต่ละครั้ง แม้ว่านี่จะทำให้ throughput ลดลงเพียงเล็กน้อยเมื่อเปรียบเทียบกับการอ่านพร้อมจริง แต่ก็อาจทำให้ประสิทธิภาพโดยรวมดีขึ้น
-
ติดตามประสิทธิภาพด้วยเมตริก: ใช้เครื่องมือการติดตามประสิทธิภาพ (เช่น
perfmon
) เพื่อตรวจสอบสถานะคิวดิสก์และปรับช่วงเวลาในการอ่านและขนาดข้อมูลของคุณแบบไดนามิก วิธีการ ‘auto-tuning’ นี้ช่วยให้คุณสามารถปรับกลยุทธ์ของคุณตามเมตริกการแสดงผลจริง:- วัดอัตราการถ่ายโอนในปัจจุบัน
- ปรับค่า X และ Y ตามข้อมูลประสิทธิภาพในอดีต
-
อัปเกรดเป็นเวอร์ชัน Windows ใหม่กว่า: หากเป็นไปได้ ให้พิจารณาอัปเกรดระบบปฏิบัติการของคุณ Windows Vista และรุ่นใหม่กว่าให้การจัดตารางดิสก์ที่ชาญฉลาดขึ้น ช่วยให้การอ่านพร้อมกันทำได้มีประสิทธิภาพมากขึ้น
สรุป
การเข้าถึงประสิทธิภาพการอ่านพร้อมกันที่ดีจากดิสก์ใน Windows ต้องการการเข้าใจถึงข้อจำกัดของการจัดตาราง I/O ของระบบปฏิบัติการและการนำเทคนิคซอฟต์แวร์ที่ชาญฉลาดมาใช้เพื่อทำงานรอบๆ โดยการนำเสนอนโยบายการเข้าถึงดิสก์ที่กำหนดเอง การใช้เทคนิคการซิงโครไนซ์ และการติดตามเมตริกประสิทธิภาพ คุณสามารถปรับปรุง throughput ของแอปพลิเคชันของคุณเมื่อทำงานกับไฟล์ขนาดใหญ่และมัลติเทรดดิ้งได้อย่างมีนัยสำคัญ
ใช้กลยุทธ์เหล่านี้อย่างรอบคอบ แล้วคุณจะก้าวสู่การเพิ่มประสิทธิภาพกระบวนการอ่านดิสก์ของคุณและใช้พลังของการเขียนโปรแกรมแบบคู่ขนานในแอปพลิเคชันของคุณอย่างเต็มที่