อ่าน 3 นาที
เธรดเสมือน
ใน การเขียนโปรแกรมคอมพิวเตอร์ เธรด เสมือน (Virtual Thread ) คือ เธรด ที่ได้รับการจัดการโดย ไลบรารีรันไทม์ หรือ เครื่องเสมือน (Virtual Machine: VM)...
เธรดเสมือน
ในการเขียนโปรแกรมคอมพิวเตอร์เธรดเสมือน (Virtual Thread ) คือเธรดที่ได้รับการจัดการโดยไลบรารีรันไทม์หรือเครื่องเสมือน (Virtual Machine: VM) และถูกสร้างขึ้นให้มีลักษณะคล้ายกับเธรดเคอร์เนลสำหรับโค้ดที่ทำงานอยู่บนนั้น ในขณะที่ต้องการทรัพยากรน้อยกว่าเธรดเคอร์เนลอย่างมาก
เธรดเสมือนช่วยให้สามารถจัดการงานและเหตุการณ์แบบแทรกแซงได้หลายสิบล้านรายการบนคอมพิวเตอร์ระดับผู้บริโภคในปี 2021 [ 1 ] เมื่อเทียบกับ เธรดระบบปฏิบัติการเพียงไม่กี่พัน รายการ [ 2 ]การดำเนินการแบบแทรกแซง[ 3 ]มีความสำคัญต่อการเพิ่มประสิทธิภาพผ่านการทำงานแบบขนานและเวลาตอบสนองแบบแทรกแซงที่รวดเร็วสำหรับเหตุการณ์หลายสิบล้านรายการ
โครงสร้างก่อนหน้านี้ที่ไม่ใช่หรือไม่ได้เป็นการชิงจังหวะเสมอไป เช่นcoroutines , green threads หรือ Node.jsที่ส่วนใหญ่เป็นเธรดเดียวทำให้เกิดความล่าช้าในการตอบสนองต่อเหตุการณ์แบบอะซิงโครนัส เช่น คำขอขาเข้าทุกรายการในแอปพลิเคชันเซิร์ฟเวอร์[ 4 ]
คำนิยาม
เธรดเสมือนสามารถแย่งชิงการทำงานได้
- สิ่งสำคัญสำหรับประสิทธิภาพการตอบสนองคือ เธรดเสมือนสามารถตอบสนองต่อเหตุการณ์ต่างๆ ได้โดยไม่ต้องมีการแทรกแซงจากโปรแกรมเมอร์ หรือก่อนที่จะเสร็จสิ้นภารกิจปัจจุบัน
- การแทรกแซงการทำงาน (Preemption) จำเป็นต้องมีความรู้เกี่ยวกับการเขียนโปรแกรมแบบมัลติเธรด เพื่อหลีกเลี่ยงการเขียนข้อมูลที่ไม่สมบูรณ์ การแข่งขันของข้อมูล และการเขียนข้อมูลที่มองไม่เห็นโดยเธรดอื่น
เธรดเสมือนสามารถข้ามไปยังหน่วยประมวลผลของโปรเซสเซอร์และคอร์ทั้งหมดได้
- วิธีนี้ช่วยให้สามารถใช้ประโยชน์จากฮาร์ดแวร์ที่มีอยู่ได้อย่างมีประสิทธิภาพมากขึ้น
- Go (ตั้งแต่เวอร์ชัน 1.18) ใช้คิวเธรดเสมือนต่อหน่วยการดำเนินการมีเธรดเสมือนเพิ่มเติมที่ไม่ได้จัดสรรให้กับหน่วยการดำเนินการ และหน่วยการดำเนินการสามารถขโมยเธรดเสมือนจากหน่วยการดำเนินการอื่นได้[ 5 ]
เธรดเสมือนไม่ต้องการคำสั่ง yield หรือการแทรกแซงใดๆ จากโปรแกรมเมอร์
- เธรดเสมือนจะทำงานอย่างต่อเนื่องจนกว่าจะส่งค่ากลับหรือหยุดที่การล็อกการซิงโครไนซ์
- ต่างจากโครูทีน หากเธรดเสมือนอยู่ในลูปไม่สิ้นสุด มันจะไม่บล็อกโปรแกรม การทำงานจะดำเนินต่อไปด้วยภาระ CPU ที่สูงขึ้น แม้ว่าจะมีเธรดที่วนลูปมากกว่าหน่วยประมวลผลที่มีอยู่ก็ตาม
เธรดเสมือนสามารถมีจำนวนนับสิบล้านได้ โดยการใช้สแต็กขนาดเล็กที่มักได้รับการจัดการ
- วิธีนี้ช่วยให้สามารถใช้งานเธรดได้มากกว่าการใช้เธรดของระบบปฏิบัติการหลายเท่าตัว
- Go 1.18 สามารถสร้างเธรดเสมือนได้ถึง 15 ล้านเธรดบนคอมพิวเตอร์ระดับผู้บริโภคปี 2021 หรือประมาณ 350,000 เธรดต่อกิกะไบต์ของหน่วยความจำหลัก ซึ่งเป็นไปได้ด้วยคุณสมบัติของ goroutine ที่มีสแต็กที่ปรับขนาดได้และมีขนาดเล็กกว่า 3 กิโลไบต์
สามารถจัดสรรเธรดเสมือนได้อย่างรวดเร็ว
- เนื่องจากการจัดสรรเธรดเสมือนมีค่าใช้จ่ายเพิ่มเติมเพียงเล็กน้อยเมื่อเทียบกับการจัดสรรหน่วยความจำ จึงสามารถจัดสรรได้อย่างรวดเร็วมาก
- การเริ่มต้นทำงานที่รวดเร็วยิ่งขึ้นช่วยลดความจำเป็นในการใช้พูลเธรดที่เปิดใช้งานล่วงหน้าเพื่อรองรับปริมาณการใช้งานที่เพิ่มขึ้นอย่างฉับพลัน
เธรดเสมือนใช้หน่วยความจำร่วมกันเช่นเดียวกับเธรดของระบบปฏิบัติการ
- เช่นเดียวกับเธรดของระบบปฏิบัติการ เธรดเสมือนจะใช้หน่วยความจำร่วมกันระหว่างกระบวนการ และสามารถใช้และเข้าถึงวัตถุในหน่วยความจำได้อย่างอิสระ โดยขึ้นอยู่กับการซิงโครไนซ์
- สถาปัตยกรรมแบบเธรดเดียวบางประเภท เช่น เอ็นจิ้น V8 ECMAScriptที่ใช้ใน Node.js ไม่ยอมรับข้อมูลที่เธรดนั้นไม่ได้จัดสรรไว้โดยตรง จึงจำเป็นต้องใช้ชนิดข้อมูลแบบzero-copy พิเศษเมื่อต้องการแชร์ข้อมูลระหว่างเธรด
เธรดเสมือนช่วยให้สามารถประมวลผลแบบขนานได้เช่นเดียวกับเธรดของระบบปฏิบัติการ
- การประมวลผลแบบขนานหมายความว่าคำสั่งหลายคำสั่งจะถูกดำเนินการพร้อมกันอย่างแท้จริง ซึ่งโดยทั่วไปจะส่งผลให้ประสิทธิภาพการทำงานเร็วขึ้นอย่างมาก
- นี่แตกต่างจากการทำงานพร้อมกันแบบง่ายๆ ซึ่งหน่วยประมวลผลเดียวจะประมวลผลหลายเธรดที่แบ่งปันกันในช่วงเวลาสั้นๆ การแบ่งเวลาทำให้แต่ละเธรดดูเหมือนกำลังทำงานอย่างต่อเนื่อง แม้ว่าการทำงานพร้อมกันจะง่ายต่อการใช้งานและเขียนโปรแกรม แต่ก็ไม่ได้ให้ประสิทธิภาพที่เพิ่มขึ้นแต่อย่างใด
แรงจูงใจ
เซิร์ฟเวอร์ Java มีโครงสร้างซอฟต์แวร์ที่กว้างขวางและใช้หน่วยความจำมาก ทำให้เธรดระบบปฏิบัติการหลายสิบเธรดสามารถดำเนินการคำขอหลายพันรายการต่อวินาทีได้โดยไม่ต้องใช้เธรดเสมือน สิ่งสำคัญต่อประสิทธิภาพในที่นี้คือการลดความหน่วงเริ่มต้นในการประมวลผลเธรดและลดเวลาที่เธรดระบบปฏิบัติการถูกบล็อกให้น้อยที่สุด[ 6 ]
เธรดเสมือนเพิ่มความสามารถในการทำงานพร้อมกันได้หลายเท่าตัว ในขณะที่ การทำงาน แบบขนานที่เกิดขึ้นจริงนั้นถูกจำกัดด้วยหน่วยประมวลผลที่มีอยู่และการประมวลผลแบบไปป์ไลน์ที่นำเสนอโดยโปรเซสเซอร์และคอร์โปรเซสเซอร์ในปัจจุบัน ในปี 2021 คอมพิวเตอร์ระดับผู้บริโภคโดยทั่วไปจะมีหน่วยประมวลผลพร้อมกันได้หลายสิบหน่วย[ 7 ]เพื่อเพิ่มประสิทธิภาพผ่านการทำงานแบบขนาน รันไทม์ของภาษาจำเป็นต้องใช้ฮาร์ดแวร์ที่มีอยู่ทั้งหมด[ 8 ] ไม่ใช่แบบเธรดเดียวหรือมีการซิงโคร ไน ซ์ทั่วโลก เช่นการล็อกตัวแปลทั่วโลก
ความสามารถในการเพิ่มจำนวนรายการที่สามารถแย่งชิงได้หลายเท่าตัวที่เสนอโดยเธรดเสมือนนั้นเกิดขึ้นได้จากการจัดการสแต็กเธรดที่ปรับขนาดได้ของรันไทม์ภาษา[ 9 ]สแต็กเหล่านั้นมีขนาดเล็กกว่าสแต็กของเธรดระบบปฏิบัติการ จำนวนเธรดสูงสุดที่เป็นไปได้โดยไม่ต้องสลับนั้นเป็นสัดส่วนกับปริมาณหน่วยความจำหลัก[ 10 ]
เพื่อรองรับเธรดเสมือนอย่างมีประสิทธิภาพ รันไทม์ของภาษาจะต้องถูกเขียนใหม่เป็นส่วนใหญ่เพื่อป้องกันการเรียกแบบบล็อกไม่ให้ขัดขวางเธรดของระบบปฏิบัติการที่ได้รับมอบหมายให้ดำเนินการเธรดเสมือน[ 11 ]และเพื่อจัดการสแต็กเธรด[ 12 ]ตัวอย่างของการปรับปรุงรันไทม์ที่มีอยู่ให้รองรับเธรดเสมือนคือProject Loomของ Java [ 13 ]ตัวอย่างของภาษาใหม่ที่ออกแบบมาสำหรับเธรดเสมือนคือ Go [ 14 ]
ความซับซ้อน
เนื่องจากเธรดเสมือนช่วยให้สามารถทำงานแบบขนานได้ โปรแกรมเมอร์จึงจำเป็นต้องมีทักษะในการเขียนโปรแกรมแบบมัลติเธรดและการซิงโครไนซ์
เนื่องจากเธรดเสมือนที่ถูกบล็อกจะบล็อกเธรดของระบบปฏิบัติการที่มันกำลังใช้งานอยู่ ณ ขณะนั้น จึงต้องใช้ความพยายามอย่างมากในขั้นตอนการทำงานเพื่อจัดการกับการเรียกใช้ระบบที่ทำให้เกิดการบล็อก โดยทั่วไปแล้ว จะใช้เธรดจากกลุ่มเธรดสำรองของระบบปฏิบัติการเพื่อเรียกใช้ฟังก์ชันที่ทำให้เกิดการบล็อกสำหรับเธรดเสมือน เพื่อไม่ให้เธรดของระบบปฏิบัติการที่กำลังทำงานอยู่ถูกบล็อก
การจัดการสแต็กเธรดเสมือนต้องใช้ความระมัดระวังในส่วนของลิงเกอร์ และการคาดการณ์ความต้องการพื้นที่สแต็กเพิ่มเติมในระยะเวลาอันสั้น
การนำไปใช้
เบราว์เซอร์ Google Chrome
เธรดเสมือนใช้สำหรับจัดลำดับกิจกรรมอินพุต/เอาต์พุตแบบซิงเกิลตัน และพร้อมใช้งานสำหรับนักพัฒนาที่ขยายเบราว์เซอร์ เมื่อเธรดเสมือนกำลังทำงาน มันสามารถกระโดดไปยังเธรดระบบปฏิบัติการอื่นได้[ 15 ]
ไป
goroutineในภาษา Go กลายเป็นแบบ preemptive ตั้งแต่ Go 1.4 ในปี 2014 และเป็นตัวอย่างที่โดดเด่นของการใช้งาน virtual threads
ชวา
Java ได้แนะนำเธรดเสมือนแบบ preemptive เป็นส่วนใหญ่ในปี 2023 ด้วย Java 21 โดยมีข้อจำกัดว่าโค้ดใดๆ ที่ทำงานบนเธรดเสมือนซึ่งใช้ บล็อก synchronizedหรือการเรียกแบบเนทีฟจะถูกตรึงไว้กับเธรดระบบปฏิบัติการหลัก[ 16 ]ข้อจำกัดดังกล่าวได้รับการแก้ไขใน Java 24 [ 17 ]
การใช้คำในรูปแบบอื่นๆ
Intel [ 18 ]ในปี 2550 ได้อ้างถึง เทคนิคการเพิ่มประสิทธิภาพเฉพาะ คอมไพเลอร์ ของ Intel ว่าเป็นเธรดเสมือน
ดูเพิ่มเติม
- อะซิงโครนัส/อะไวต์
- กระบวนการน้ำหนักเบา
- โครูทีน
- การล็อกตัวแปลภาษาทั่วโลก
- ไฟเบอร์ (วิทยาการคอมพิวเตอร์)
- GNU Portable Threads
- โปรโตเธรด
ลิงก์ภายนอก
- massivevirtualparallelism โปรแกรม Go ทดสอบข้อจำกัดของเธรดเสมือน
สรุปเนื้อหา
ข้อมูลสำคัญจากบทความ
ข้อมูลสำคัญเกี่ยวกับ เธรดเสมือน
ใน การเขียนโปรแกรมคอมพิวเตอร์ เธรด เสมือน (Virtual Thread ) คือ เธรด ที่ได้รับการจัดการโดย ไลบรารีรันไทม์ หรือ เครื่องเสมือน (Virtual Machine: VM)...
แรงจูงใจ
เซิร์ฟเวอร์ Java มีโครงสร้างซอฟต์แวร์ที่กว้างขวางและใช้หน่วยความจำมาก ทำให้เธรดระบบปฏิบัติการหลายสิบเธรดสามารถดำเนินการคำขอหลายพันรายการต่อวินาทีได้โดยไม่ต้องใช้เธรดเสมือน...
ความซับซ้อน
เนื่องจากเธรดเสมือนช่วยให้สามารถทำงานแบบขนานได้ โปรแกรมเมอร์จึงจำเป็นต้องมีทักษะในการเขียนโปรแกรมแบบมัลติเธรดและการซิงโครไนซ์
เบราว์เซอร์ Google Chrome
เธรดเสมือนใช้สำหรับจัดลำดับกิจกรรมอินพุต/เอาต์พุตแบบซิงเกิลตัน และพร้อมใช้งานสำหรับนักพัฒนาที่ขยายเบราว์เซอร์ เมื่อเธรดเสมือนกำลังทำงาน มันสามารถกระโดดไปยังเธรดระบบปฏิบัติการอื่นได้ [ 15 ]