“ ตัวแทน; นพ;” ค่าเฉลี่ยในการประกอบ x86? เหมือนกับคำสั่ง "หยุดชั่วคราว" หรือไม่


86
  • อะไรrep; nopหมายถึง?
  • เหมือนกับการpauseเรียนการสอนหรือไม่?
  • มันเหมือนกับrep nop(ไม่มีอัฒภาค) หรือไม่?
  • nopคำสั่งง่ายๆแตกต่างกันอย่างไร?
  • มันทำงานแตกต่างกันในโปรเซสเซอร์ AMD และ Intel หรือไม่?
  • (โบนัส) เอกสารอย่างเป็นทางการสำหรับคำแนะนำเหล่านี้อยู่ที่ไหน?

แรงจูงใจสำหรับคำถามนี้

หลังจากการสนทนาในความคิดเห็นของคำถามอื่นฉันตระหนักว่าฉันไม่รู้ว่าrep; nop;หมายความว่าอย่างไรในการประกอบ x86 (หรือ x86-64) และฉันไม่พบคำอธิบายที่ดีในเว็บ

ฉันรู้ว่านั่นrepคือคำนำหน้าซึ่งหมายถึง"ทำซ้ำคำสั่งcxครั้งต่อไป" (หรืออย่างน้อยก็คือในแอสเซมบลี x86 16 บิตเก่า) ตามนี้ตารางสรุปที่วิกิพีเดียดูเหมือนว่าrepสามารถนำมาใช้เฉพาะกับmovs, stos, cmps, lods, scas( แต่บางทีข้อ จำกัด นี้จะถูกลบออกในโปรเซสเซอร์ใหม่กว่า) ดังนั้นฉันคิดว่าrep nop(ไม่ลำไส้ใหญ่กึ่ง) จะทำซ้ำnopการดำเนินการcxครั้ง

อย่างไรก็ตามหลังจากค้นหาเพิ่มเติมฉันก็ยิ่งสับสน ดูเหมือนว่าrep; nopและpause แมปกับ opcode เดียวกันและpauseมีพฤติกรรมที่แตกต่างจากเพียงnopเล็กน้อย จดหมายเก่าบางฉบับจากปี 2548กล่าวถึงสิ่งที่แตกต่างกัน:

  • “ พยายามอย่าเผาผลาญพลังงานมากเกินไป”
  • "เทียบเท่ากับ 'nop' เพียงแค่เข้ารหัส 2 ไบต์"
  • "มันคือเวทย์มนตร์บน intel มันเหมือนกับ 'nop แต่ปล่อยให้พี่น้อง HT คนอื่นวิ่ง'"
  • "มันหยุดชั่วคราวบน intel และการขยายอย่างรวดเร็วบน Athlon"

ด้วยความคิดเห็นที่แตกต่างกันเหล่านี้ฉันไม่เข้าใจความหมายที่ถูกต้อง

มันถูกใช้ในเคอร์เนลลินุกซ์ (ทั้งบนi386และx86_64 ) พร้อมกับความคิดเห็นนี้: /* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */มันยังถูกใช้ใน BeRTOSด้วยความคิดเห็นเดียวกัน


2
ที่เกี่ยวข้อง: stackoverflow.com/questions/12894078/pause-instruction-in-x86
jfritz42

คำตอบ:


75

rep; nopแน่นอนเหมือนกับpauseคำสั่ง (opcode F390) อาจใช้สำหรับแอสเซมเบลอร์ที่ยังไม่รองรับpauseคำสั่ง ในโปรเซสเซอร์รุ่นก่อนหน้านี้ไม่ได้ทำอะไรเลยเช่นเดียวกับnopแต่เป็นสองไบต์ สำหรับโปรเซสเซอร์รุ่นใหม่ที่รองรับไฮเปอร์เธรดจะใช้เป็นคำใบ้ให้โปรเซสเซอร์ทราบว่าคุณกำลังเรียกใช้งานสปินลูปเพื่อเพิ่มประสิทธิภาพ จากข้อมูลอ้างอิงคำแนะนำของ Intel :

ปรับปรุงประสิทธิภาพของการหมุนวนรอ เมื่อดำเนินการ "spin-wait loop" โปรเซสเซอร์ Pentium 4 หรือ Intel Xeon จะได้รับโทษด้านประสิทธิภาพอย่างรุนแรงเมื่อออกจากลูปเนื่องจากตรวจพบการละเมิดลำดับหน่วยความจำที่อาจเกิดขึ้น คำสั่ง PAUSE ให้คำแนะนำแก่โปรเซสเซอร์ว่าลำดับรหัสเป็นวงรอบหมุนรอ โปรเซสเซอร์ใช้คำใบ้นี้เพื่อหลีกเลี่ยงการละเมิดคำสั่งหน่วยความจำในสถานการณ์ส่วนใหญ่ซึ่งช่วยเพิ่มประสิทธิภาพของโปรเซสเซอร์ได้อย่างมาก ด้วยเหตุนี้ขอแนะนำให้วางคำสั่ง PAUSE ไว้ในลูปรอหมุนทั้งหมด


4
เป็นห่วงปั่นรอเช่นเดียวกับวงยุ่งรอ ? "การปรับปรุง" นี้ใช้กับโปรเซสเซอร์ไฮเปอร์เธรดเท่านั้นหรือไม่? (และทำไม?)
Denilson Sá Maia

11
ใช่ Spin-wait loop เหมือนกับ busy-wait loop ประโยชน์ยังใช้ได้กับซีพียูที่ไม่รองรับไฮเปอร์เธรด อาจคิดได้ว่าเป็นการ จำกัด จำนวนคำสั่ง (ไม่จำเป็น) ในไปป์ไลน์ (แทนที่จะพยายามทำวนซ้ำหลาย ๆ รอบแบบขนาน)
เบรนแดน

1
@ เบรนแดนขอบคุณ! ฉันไม่เข้าใจเลยจนกว่าคุณจะพูดเรื่องการวนซ้ำแบบขนาน
ศ. Falken

11
@ เบรนแดนโอ้ตอนนี้ฉันเข้าใจแล้ว! โปรเซสเซอร์ที่ทันสมัยเหล่านี้เป็นซูเปอร์คาร์ดังนั้นพวกเขาจะพยายามเรียกใช้คำสั่งหลายคำสั่งในเวลาเดียวกัน หากนี่เป็นวนรอบการรอที่วุ่นวายการรันคำสั่งเพิ่มเติมจะไม่ทำให้เร็วขึ้นเนื่องจากกำลังรอเงื่อนไขอื่น
Denilson Sá Maia

1
@Denilson: ใช่ความเป็นมิตรต่อไฮเปอร์เธรด (หรือเพียงแค่ประหยัดพลังงานโดยไม่ใช้ HT) เป็นข้อดีอย่างหนึ่ง แต่อีกอย่างหนึ่งคือการหลีกเลี่ยงการเก็งกำไรที่ผิดพลาดในการสั่งซื้อหน่วยความจำเมื่อออกจากวงหมุน หากไม่มีการpauseหมุนวนของคุณจะล้างไปป์ไลน์ช้าลงอย่างมีประสิทธิภาพเพื่อสังเกตการเปลี่ยนแปลงสถานะของตำแหน่งหน่วยความจำที่เขียนโดยคอร์อื่น
Peter Cordes

15

rep nop= F3 90 = การเข้ารหัสสำหรับเช่นเดียวกับวิธีการที่จะถอดรหัสบนซีพียูรุ่นเก่าที่ไม่สนับสนุนpausepause


คำนำหน้า (นอกเหนือจากlock) ที่ไม่ใช้กับคำสั่งจะถูกละเว้นในทางปฏิบัติโดย CPU ที่มีอยู่

เอกสารระบุว่าการใช้repพร้อมคำแนะนำที่ใช้ไม่ได้คือ"สงวนไว้และอาจทำให้เกิดพฤติกรรมที่คาดเดาไม่ได้" เนื่องจากซีพียูในอนาคตอาจรับรู้ว่าเป็นส่วนหนึ่งของคำสั่งใหม่ เมื่อพวกเขาสร้างการเข้ารหัสคำสั่งใหม่โดยใช้f3 xxแล้วพวกเขาจะจัดทำเอกสารว่ามันทำงานบน CPU รุ่นเก่าอย่างไร (ใช่พื้นที่ opcode x86 มี จำกัด มากจนทำเรื่องบ้าๆแบบนี้และใช่มันทำให้ตัวถอดรหัสซับซ้อน)

ในกรณีนี้ก็หมายความว่าคุณสามารถใช้pauseใน spinloops โดยไม่ทำลาย compat ซีพียูเก่าที่ไม่ทราบเกี่ยวกับpauseจะถอดรหัสเป็น NOP กับทำอันตรายไม่เป็นประกันโดยคู่มือของ Intel ISA เตะรายการสำหรับ pauseสำหรับซีพียูรุ่นใหม่คุณจะได้รับประโยชน์จากการประหยัดพลังงาน / เป็นมิตรกับ HT และหลีกเลี่ยงการคาดเดาที่ผิดพลาดในการจัดลำดับหน่วยความจำเมื่อหน่วยความจำที่คุณกำลังหมุนเปลี่ยนไปและคุณออกจากวงหมุน


ลิงก์ไปยังคู่มือของ Intel และสิ่งดีๆอีกมากมายในหน้าข้อมูลวิกิแท็ก x86

อีกกรณีหนึ่งของความหมายrepคำนำหน้ากลายเป็นคำแนะนำใหม่บนซีพียูใหม่ เป็นlzcnt F3 0F BD /rบน CPU ที่ไม่รองรับคำสั่งนั้น (ไม่มีแฟล็กคุณลักษณะ LZCNT ใน CPUID) จะถอดรหัสเป็นrep bsrซึ่งทำงานเหมือนกับbsrไฟล์. ดังนั้นในซีพียูรุ่นเก่าจะสร้าง32 - expected_resultและไม่ได้กำหนดเมื่ออินพุตเป็นศูนย์

แต่tzcntและbsfทำสิ่งเดียวกันกับอินพุตที่ไม่ใช่ศูนย์ดังนั้นคอมไพเลอร์สามารถและใช้งานtzcntได้แม้ว่าจะไม่รับประกันว่า CPU เป้าหมายจะเรียกใช้เป็นtzcnt. ซีพียู AMD มีเร็วtzcntช้าbsfและใน Intel ก็เร็วทั้งคู่ ตราบเท่าที่มันไม่สำคัญสำหรับความถูกต้อง (คุณไม่ได้อาศัยการตั้งค่าสถานะหรือปล่อยให้พฤติกรรมที่ไม่ได้แก้ไขปลายทางในกรณีอินพุต = 0) การถอดรหัสเช่นเดียวtzcntกับซีพียูที่รองรับจะเป็นประโยชน์


กรณีหนึ่งของrepคำนำหน้าไร้ความหมายซึ่งอาจจะไม่มีวันถอดรหัสแตกต่างกัน: rep retถูกใช้โดยค่าเริ่มต้นโดย gcc เมื่อกำหนดเป้าหมายซีพียู "ทั่วไป" (เช่นไม่กำหนดเป้าหมาย CPU เฉพาะที่มี-marchหรือ-mtuneและไม่กำหนดเป้าหมายไปที่ AMD K8 หรือ K10) จะเป็นเวลาหลายสิบปีก่อนใคร สามารถสร้าง CPU ที่ถอดรหัสrep retเป็นอย่างอื่นได้retเนื่องจากมีอยู่ในไบนารีส่วนใหญ่ใน Linux distros ส่วนใหญ่ ดู ว่า "rep ret" หมายความว่าอย่างไร


3
repคำนำหน้ายังถูกนำมาใช้โดย Intel เพื่อเพิ่มสลัดล็อค
Paul A. Clayton

คำนำหน้าที่ไม่ใช้กับคำสั่งจะถูกละเว้น แต่มีการกล่าวถึงคำนำหน้าซ้ำ ( F2HและF3H) สงวนไว้และอาจส่งผลให้เกิดพฤติกรรมที่ไม่สามารถคาดเดาได้ในตารางที่ 11-3 ผลของการใช้คำนำหน้าใน SSE, SSE2, SSE3 และคำแนะนำ ดังนั้นแอปพลิเคชันคำนำหน้าจะถูกละเว้นสำหรับคำแนะนำบางอย่างไม่ใช่สำหรับทั้งหมด คุณลักษณะนี้ถือว่าไม่มีเอกสารหรือไม่?
St.Antario

2
@ เซนต์แอนทาริโอ: พวกเขาพูดแบบนั้นเพราะซีพียูในอนาคตอาจรับรู้ว่าเป็นส่วนหนึ่งของคำสั่งใหม่ ในซีพียูจริงทั้งหมดที่เป็นเช่นนั้นและเมื่อพวกเขาสร้างการเข้ารหัสโดยใช้f3 xxเอกสารว่ามันทำงานบนซีพียูรุ่นเก่าอย่างไร
Peter Cordes

1
คำนำหน้า (นอกเหนือจากการล็อก) ที่ไม่ใช้กับคำสั่งจะถูกละเลยในทางปฏิบัติโดย CPU ที่มีอยู่ มีการบันทึกไว้ว่าrep movbeสาเหตุ#UDดังนั้นจึงrepไม่ควรละเลยเสมอไป แม้ว่าจะใช้ไม่ได้กับคำสั่งตามความหมายตามที่ระบุไว้ในREP/REPE/REPZ/REPNE/REPNZรายการคู่มือ
St.Antario

2
@ St.Antario: น่าสนใจ! โดยทั่วไปแล้วสำหรับคำแนะนำที่เก่ากว่าคำนำหน้าที่ไม่เกี่ยวข้องจะถูกละเว้น เมื่อแนะนำคำสั่งใหม่คุณสามารถเพิ่มกฎที่เข้มงวดขึ้นได้หากพวกเขาเลือก IDK ทำไมพวกเขาถึงเลือกแบบนั้นสำหรับกรณีนี้
Peter Cordes
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.