“ สปินล็อก” คืออะไร?


108

ฉันสงสัยอยู่เสมอว่าพวกมันคืออะไรทุกครั้งที่ฉันได้ยินเกี่ยวกับพวกเขาภาพของอุปกรณ์ที่คล้ายล้อฟลายเวลล้ำยุคกำลังเต้น (กลิ้ง?) ผ่านความคิดของฉัน ...

พวกเขาคืออะไร?

คำตอบ:


126

เมื่อคุณใช้ล็อคปกติ (mutexes ส่วนสำคัญ ฯลฯ ), ระบบปฏิบัติการทำให้หัวข้อของคุณอยู่ในสถานะรอและpreemptsมันโดยการตั้งเวลาหัวข้ออื่น ๆ บนแกนเดียวกัน สิ่งนี้มีผลเสียหากเวลาในการรอสั้นจริงๆเนื่องจากเธรดของคุณต้องรอใบจองเพื่อรับเวลา CPU อีกครั้ง

นอกจากนี้เคอร์เนลอ็อบเจ็กต์ยังไม่พร้อมใช้งานในทุกสถานะของเคอร์เนลเช่นในตัวจัดการขัดจังหวะหรือเมื่อไม่มีการเพจเป็นต้น

Spinlocks ไม่ทำให้ใบจอง แต่รอวนซ้ำ ("หมุน") จนกว่าคอร์อื่น ๆ จะคลายล็อก วิธีนี้จะป้องกันไม่ให้เธรดสูญเสียควอนตัมและดำเนินการต่อทันทีที่คลายล็อก กลไกง่ายๆของ spinlocks ช่วยให้เคอร์เนลสามารถใช้งานได้ในเกือบทุกสถานะ

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

Spinlocks ช่วยให้เมล็ดสามารถหลีกเลี่ยง "Big Kernel Lock" ได้ในที่สุด (ล็อคที่ได้มาเมื่อคอร์เข้าสู่เคอร์เนลและปล่อยออกที่ทางออก) และมีการล็อกแบบละเอียดบนเคอร์เนลแบบดั้งเดิมทำให้เกิดการประมวลผลแบบมัลติคอร์ที่ดีขึ้นบนเครื่องมัลติคอร์จึงมีประสิทธิภาพที่ดีขึ้น

แก้ไข : มีคำถามเกิดขึ้น: "นั่นหมายความว่าฉันควรใช้ Spinlock ทุกที่ที่เป็นไปได้หรือไม่" และฉันจะพยายามตอบ:

ดังที่ฉันได้กล่าวไปแล้ว Spinlocks มีประโยชน์เฉพาะในสถานที่ที่เวลารอคอยที่คาดไว้จะสั้นกว่าควอนตัม (อ่าน: มิลลิวินาที) และใบจองไม่สมเหตุสมผลมากนัก (เช่นเคอร์เนลออบเจ็กต์ไม่มี)

หากไม่ทราบเวลารอหรือหากคุณอยู่ในโหมดผู้ใช้ Spinlocks ไม่มีประสิทธิภาพ คุณใช้เวลา CPU 100% บนคอร์รอขณะตรวจสอบว่ามีสปินล็อกหรือไม่ คุณป้องกันไม่ให้เธรดอื่นทำงานบนคอร์นั้นจนกว่าควอนตัมของคุณจะหมดอายุ สถานการณ์นี้เป็นไปได้สำหรับการระเบิดสั้น ๆ ที่ระดับเคอร์เนลและไม่น่าจะเป็นตัวเลือกสำหรับแอ็พพลิเคชันโหมดผู้ใช้

นี่คือคำถามเกี่ยวกับ SO ที่ระบุว่าSpinlocks มีประโยชน์อย่างไร?


หมายความว่าฉันควรหมุนล็อค (แทนที่จะเป็น mutex, ส่วนวิกฤต ฯลฯ ) ทุกที่ที่เป็นไปได้?

1
ใครก็ได้โปรดแก้ไขฉันหากฉันผิด แต่ Spinlock ไม่ปิดการใช้งานใบจอง (เช่นการตั้งเวลาใหม่) ด้วยเหตุผลง่ายๆว่าหาก Spinlock กำลังรอทรัพยากรที่ถูกล็อกโดยกระบวนการอื่นกระบวนการที่สองนั้นจะต้องได้รับโอกาสในการรันและปลดปล่อยทรัพยากร หรือการเรียกใช้กระบวนการที่สองจำเป็นต้องมีการทดลองขั้นตอนแรก (การปั่นด้าย) ก่อน
user1284631

สิ่งที่ spinlock ทำแทนคือมันไม่เปลี่ยนสถานะกระบวนการจาก TASK_RUNNING เป็น TASK_INTERRUPTIBLE (ซึ่งเป็นสถานะสลีป) ดังนั้นจึงไม่บันทึกทุกอย่างเกี่ยวกับกระบวนการนั้น (หน่วยความจำแคชและอื่น ๆ ) แทนกระบวนการปั่นจะถูกจองไว้ล่วงหน้า แต่ไม่เคยออกจากกระบวนการ "กำหนดตารางเวลาได้ทันที" กระบวนการนี้จะถูกเก็บไว้ในหน่วยความจำและกระบวนการอื่น ๆ จะทำงานอย่างสม่ำเสมอจนกว่าหนึ่งในนั้นจะปลดปล่อยทรัพยากรที่สปินเนอร์กำลังรออยู่: ในขณะนั้น Spinlock เพียงแค่ส่งคืนและกระบวนการปั่นสามารถดำเนินต่อไปได้ มันจะรออยู่ในสถานะ TASK_RUNNING เสมอ
user1284631

1
คุณเข้าใจถูกแล้ว (ดูสิ่งนี้ด้วยlinuxjournal.com/article/5833 ) แต่ความจริงก็คือการล็อก ressource และการปิดใช้งานการขัดจังหวะแม้ว่าจะมีประโยชน์ในการดำเนินการร่วมกัน แต่ก็เป็นแนวคิดที่ไม่เกี่ยวข้องกัน โดยพื้นฐานแล้วคุณต้องแน่ใจว่าคุณไม่ได้ใช้ทรัพยากรที่พบในสถานะที่ไม่สอดคล้องกันและนี่คือเหตุผลที่คุณทดสอบการล็อก การปิดใช้งานการขัดจังหวะ (เช่นใบจอง) ช่วยให้มั่นใจได้ว่าใช่ไม่มีใครจะยุ่งกับการฟื้นคืนชีพของคุณในขณะที่คุณกำลังจัดการกับมัน แต่ด้วยเหตุนี้คุณต้องแน่ใจว่าทรัพยากรนั้นฟรีเมื่อคุณได้มา
user1284631

1
(จากนั้นปิดการใช้งานการขัดจังหวะเพื่อให้แน่ใจว่าไม่มีงานอื่นใดที่ขัดขวางคุณและยุ่งกับทรัพยากร) บน UP (uni-processor) จะเป็นเช่นนั้นเสมอ: Spinlock ตัวแรก (และรุ่นที่ตามมา) จะได้รับเพียงแค่การขัดจังหวะ (เช่นใบจอง) จะถูกปิดใช้งานและงานที่ใช้ทรัพยากรจะไม่ถูกตัดทอน: มันทำทุกอย่าง ทำงานกับทรัพยากรจากนั้นเปิดใช้งานการขัดจังหวะ (และดังนั้นใบจอง) เมื่อเปิดใช้งานใบจองแสดงว่าทรัพยากรนั้นฟรีอยู่แล้ว พื้นบนขึ้นไม่มีการต่อสู้ spinlockและไม่มีการรอคอย บน SMP อาจเป็นได้
user1284631

25

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


2
คำตอบที่ดี! +1
Jayesh Bhoi

18

มันเป็นห่วงมากที่จะดำเนินต่อไปจนกว่าจะตรงตามเงื่อนไข:

while(cantGoOn) {};

1
และ / หรือ while (cantGoOn) {sleep (0)};
Jiminion

@ Jiminion ถ้าคุณใส่sleep(0)มันจะเอาไว้ก่อนด้ายฆ่าจุดประสงค์ของการใช้ spinlock ในตอนแรก หากคุณต้องการยอมให้กับเธรดอื่นคุณควรใช้การล็อกแบบปกติ (ฉันรู้ว่าความคิดเห็นของคุณเก่ามาก แต่ต้องการป้องกันไม่ให้คนอื่นเห็นว่าเป็นคำแนะนำ)
Sedat Kapanoglu

"ค่าเป็นศูนย์ทำให้เธรดต้องสละเวลาที่เหลือไปยังเธรดอื่น ๆ ที่พร้อมจะรันหากไม่มีเธรดอื่นที่พร้อมจะรันฟังก์ชันจะคืนค่าทันทีและเธรดจะดำเนินการต่อไป"
Jiminion


5

เป็นล็อคประเภทหนึ่งที่ไม่ว่างรอ

ถือเป็นการต่อต้านรูปแบบยกเว้นสำหรับการเขียนโปรแกรมไดรเวอร์ระดับต่ำมาก (ซึ่งอาจเกิดขึ้นได้ที่การเรียกฟังก์ชันการรอ "ที่เหมาะสม" มีค่าใช้จ่ายมากกว่าการล็อกไม่ว่างเพียงไม่กี่รอบ)

ดูตัวอย่างspinlocks ในลินุกซ์เคอร์เนล


3

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

เช่น:

While(SpinCount-- && Kernel Object is not free)
{}

try acquiring Kernel object

3

คุณต้องการใช้ Spinlock เมื่อคุณคิดว่าราคาถูกกว่าในการเข้าสู่วงรอบการรอที่วุ่นวายและรวมทรัพยากรแทนการบล็อกเมื่อทรัพยากรถูกล็อค

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

สิ่งสำคัญที่ควรทราบคือ SpinLock เป็นประเภทค่าด้วยเหตุผลด้านประสิทธิภาพ ด้วยเหตุนี้เราจึงต้องระมัดระวังอย่างยิ่งที่จะไม่คัดลอกอินสแตนซ์ SpinLock โดยไม่ได้ตั้งใจเนื่องจากทั้งสองอินสแตนซ์ (ต้นฉบับและสำเนา) จะเป็นอิสระจากกันโดยสิ้นเชิงซึ่งอาจนำไปสู่พฤติกรรมที่ผิดพลาดของแอปพลิเคชัน หากต้องส่งอินสแตนซ์ SpinLock ไปรอบ ๆ อินสแตนซ์นั้นควรถูกส่งผ่านโดยการอ้างอิงแทนที่จะเป็นค่า


1

โดยสรุป Spinlock ใช้การเปรียบเทียบและแลกเปลี่ยนอะตอม (CAS) หรือคำแนะนำในการทดสอบและตั้งค่าเช่นเดียวกับการใช้งานแบบล็อคฟรีรอสำนวนที่ปลอดภัยสำหรับเธรดฟรี โครงสร้างดังกล่าวปรับขนาดได้ดีในเครื่องมัลติคอร์


ตามความหมายมากแล้ว spinlock ไม่ได้ใช้เพื่อใช้งานอะไรที่ไม่ต้องล็อคหรือรอฟรี
rdb


0

ใช่แล้ว - จุดของการล็อคการหมุน (เทียบกับส่วนที่สำคัญแบบดั้งเดิม ฯลฯ ) คือพวกเขาให้ประสิทธิภาพที่ดีขึ้นภายใต้สถานการณ์บางอย่าง (ระบบมัลติคอร์ .. ) เนื่องจากไม่ได้ให้ควอนตัมที่เหลือในทันที


0

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.