เมื่อคุณเริ่มหลายเธรดในตัวประมวลผลแบบมัลติคอร์พวกเขารับประกันว่าจะถูกประมวลผลด้วยแกนที่แตกต่างกันหรือไม่?


24

ฉันมีโปรเซสเซอร์ Pentium core i5 ซึ่งมี 4 คอร์ ถ้าฉันทำเช่นนี้ในโปรแกรมคอนโซล C #

var t1 = new Thread(Thread1);
var t2 = new Thread(Thread2);
t1.Start();
t2.Start();

มีการรับประกันว่าเธรด t1 และ t2 จะทำงานบนแกนที่แยกกันหรือไม่


1
สมมติว่า C # runtime ใช้การเรียกระบบที่เทียบเท่าเพื่อวางไข่เธรดอื่น (และขนานกันอย่างแท้จริงนี่ไม่ใช่กรณีสำหรับทุกสิ่งเช่น CPython Global Interpreter Lock ที่น่าอับอาย) สิ่งนี้จะขึ้นอยู่กับกระบวนการ / ตัวกำหนดเวลางานของระบบปฏิบัติการเท่านั้น โดยทั่วไปแล้วรหัสจะปลอดภัยอย่างแท้จริงถ้าคุณคิดt1และt2ดำเนินการในเวลาที่ต่างกันตามลำดับโดยพลการ (เช่นเป็นไปได้ที่จะt2เริ่มก่อน t1ในบางรุ่น)
พัฒนา

2
ฉันไม่รู้ว่ามีโปรเซสเซอร์ Pentium i5 บางทีคุณอาจหมายถึง Core i5 จู้จี้จุกจิก ฉันรู้: D
JosephGarrone

คำตอบ:


18

คุณไม่สามารถรับประกันใน. Net ที่ทั้งสองThreadทำงานบนสองคอร์แยกกัน ในความเป็นจริงคุณยังไม่สามารถรับประกันได้ว่าหนึ่งThreadจะทำงานเพียงหนึ่งหลัก (!)

นี่เป็นเพราะเธรดที่ได้รับการจัดการไม่เหมือนกับเธรด OS - เธรดที่มีการจัดการเดียวอาจใช้หลายเธรด OS เพื่อสนับสนุน ใน C # คุณเท่านั้นที่เคยจัดการโดยตรงกับการจัดการThreads (อย่างน้อยโดยไม่ต้อง resorting P / วิงวอนขอเรียกฟังก์ชั่น WinAPI เกลียวซึ่งคุณไม่ควรทำ)

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


ในทางปฏิบัติ. Net Threads เป็นเธรด OS แต่นั่นไม่ใช่เหตุผลที่ไม่มีการรับประกันว่าเธรดเดี่ยวจะทำงานบนแกนเดียวกันเสมอ
svick

2
@svick: ในทางปฏิบัติบน x86นั่นเป็นความจริง อย่างไรก็ตามมาตรฐานระบุไว้อย่างชัดเจนว่าคุณไม่สามารถพึ่งพาพฤติกรรมนี้ได้ดังนั้นจึงอาจเปลี่ยนแปลงได้ในอนาคต ในความเป็นจริงมันไม่เป็นความจริงใน. NET CLR รุ่นอื่นเช่น XBox 360
BlueRaja - Danny Pflughoeft

@BlueRaja - คำถามนี้เจาะจงเกี่ยวกับ CLR รุ่นที่เรากำลังพูดถึง คุณสามารถรับประกันสิ่งที่จะมีอยู่ในสองคอร์แยกจากกันโดยใช้เธรด async เพราะมันหมายความว่าพวกเขาจะเกิดขึ้น async จากกันและกัน ตัวอย่างรหัสปัจจุบันคือการโทรแบบซิงค์ แน่นอนว่าระบบปฏิบัติการจะตัดสินว่าจะใช้แกนประมวลผลใด
Ramhound

@Ramhound "คุณสามารถรับประกันสิ่งที่จะมีอยู่ในสองคอร์แยกโดยใช้เธรด async" - นั่นเป็นเท็จ asyncคำหลัก(ซึ่งเป็นสิ่งที่ผมถือว่าคุณกำลังพูดถึงเป็น "หัวข้อ async" ซ้ำซ้อน)เป็นเพียงการสร้างประโยคน้ำตาลสำหรับการใช้BackgroundWorkerด้ายซึ่งเป็นเหมือนด้ายสุทธิอื่น ๆ - คุณไม่สามารถรับประกันว่ามันจะทำงานบน แยกแกนหรือไม่
BlueRaja - Danny Pflughoeft

@BlueRaja - หากเธรด async ทั้งสองเริ่มทำงานพวกเขาทั้งสองจะทำงานในเวลาเดียวกันหากมี 2 คอร์ CPU หากมีเพียงหนึ่งระบบปฏิบัติการจะจัดตารางเวลาเมื่อแต่ละเธรดจะได้รับความสำคัญและทำงานและสถานการณ์การเฆี่ยนของเธรดเดี่ยวทั่วไปของคุณจะเกิดขึ้น นี่คือวิธีที่ฉันได้รับการสอนว่า CPU จัดการกับหลายเธรดได้อย่างไร
Ramhound

15

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

คุณสามารถใช้ความสัมพันธ์ของเธรดเพื่อพยายามควบคุมการจัดสรรคอร์ให้กับเธรดที่กำหนด

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


1
ฉันต้องการเพิ่มด้วยเทคโนโลยี virtualization มีอีกเลเยอร์ระหว่างโปรแกรมของคุณกับฮาร์ดแวร์ สิ่งที่ระบบปฏิบัติการนำเสนอต่อแอปพลิเคชันอาจไม่ถูกต้องทางร่างกาย
Keltari

1
สิ่งเหล่านี้เป็นฟังก์ชั่น WinAPI สำหรับเธรด OS ไม่ใช่สำหรับเธรดที่ได้รับการจัดการ ไม่ควรเรียกใช้จาก C # เนื่องจากอาจรบกวนตัวจัดกำหนดการเธรด. Net อย่างรุนแรง
BlueRaja - Danny Pflughoeft
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.