วิธีการเข้าถึงประสิทธิภาพการอ่านพร้อมกันที่ดีจากดิสก์ใน 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 หรือแม้แต่ในรุ่นที่ใหม่กว่าหากยังคงมีปัญหาอยู่?

วิธีการที่เสนอเพื่อปรับปรุงประสิทธิภาพการอ่านพร้อมกัน

  1. นโยบายการเข้าถึงดิสก์ที่สร้างเอง: เนื่องจากคุณไม่สามารถปรับเปลี่ยนนโยบายการจัดตารางในเวอร์ชัน 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
      

    นโยบายนี้แนะนำกลไกการรอซึ่งเธรดจะเข้าถึงดิสก์ได้เฉพาะเมื่อเธรดอื่นไม่กำลังอ่านอยู่ ซึ่งช่วยลดปัญหาการค้นหา

  2. ใช้ Primitive การซิงค์: ใช้ semaphore หรือ mutex เพื่อควบคุมการเข้าถึงดิสก์ มั่นใจได้ว่ามีเพียงเธรดเดียวที่อ่านในแต่ละครั้ง แม้ว่านี่จะทำให้ throughput ลดลงเพียงเล็กน้อยเมื่อเปรียบเทียบกับการอ่านพร้อมจริง แต่ก็อาจทำให้ประสิทธิภาพโดยรวมดีขึ้น

  3. ติดตามประสิทธิภาพด้วยเมตริก: ใช้เครื่องมือการติดตามประสิทธิภาพ (เช่น perfmon) เพื่อตรวจสอบสถานะคิวดิสก์และปรับช่วงเวลาในการอ่านและขนาดข้อมูลของคุณแบบไดนามิก วิธีการ ‘auto-tuning’ นี้ช่วยให้คุณสามารถปรับกลยุทธ์ของคุณตามเมตริกการแสดงผลจริง:

    • วัดอัตราการถ่ายโอนในปัจจุบัน
    • ปรับค่า X และ Y ตามข้อมูลประสิทธิภาพในอดีต
  4. อัปเกรดเป็นเวอร์ชัน Windows ใหม่กว่า: หากเป็นไปได้ ให้พิจารณาอัปเกรดระบบปฏิบัติการของคุณ Windows Vista และรุ่นใหม่กว่าให้การจัดตารางดิสก์ที่ชาญฉลาดขึ้น ช่วยให้การอ่านพร้อมกันทำได้มีประสิทธิภาพมากขึ้น

สรุป

การเข้าถึงประสิทธิภาพการอ่านพร้อมกันที่ดีจากดิสก์ใน Windows ต้องการการเข้าใจถึงข้อจำกัดของการจัดตาราง I/O ของระบบปฏิบัติการและการนำเทคนิคซอฟต์แวร์ที่ชาญฉลาดมาใช้เพื่อทำงานรอบๆ โดยการนำเสนอนโยบายการเข้าถึงดิสก์ที่กำหนดเอง การใช้เทคนิคการซิงโครไนซ์ และการติดตามเมตริกประสิทธิภาพ คุณสามารถปรับปรุง throughput ของแอปพลิเคชันของคุณเมื่อทำงานกับไฟล์ขนาดใหญ่และมัลติเทรดดิ้งได้อย่างมีนัยสำคัญ

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