การคาดคะเนสาขาทำงานอย่างไรถ้าคุณยังต้องตรวจสอบเงื่อนไข


30

ฉันกำลังอ่านคำตอบยอดนิยมเกี่ยวกับการทำนายสาขาจากhttps://stackoverflow.com/q/11227809/555690และมีบางอย่างที่ทำให้ฉันสับสน:

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

หากคุณเดาถูกทุกครั้งรถไฟจะไม่หยุด

หากคุณเดาผิดบ่อยเกินไปรถไฟจะใช้เวลาหยุดมาก ๆ ในการสำรองและรีสตาร์ท

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

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


1
นี้วิกิพีเดียบทความไม่ได้งานที่ดีงามอธิบาย
enderland

8
ซีพียูที่ทันสมัยนั้นถูกวางท่อและสามารถทำหลายอย่างในเวลาเดียวกัน ดังนั้นจึงสามารถเริ่มดำเนินการคาดเดาได้ในขณะที่มันยังคงคิดออกหากเดาถูก หากการเดาถูกต้องท่อส่งจะยังคงทำงานต่อไป ผิดคาดเดาไปป์ไลน์ถูกโยนออกและการดำเนินการรีสตาร์ทจากจุด "คำตอบที่ถูกต้อง"
markspace

2
การอ่านที่เกี่ยวข้อง: ท่อ ฉันจะแนะนำให้อ่านคำตอบที่ยอมรับในคำถาม SO นั้นอีกครั้งเพราะมันจะตอบคำถามของคุณที่นี่

คำตอบ:


19

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

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

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

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

การแก้ไข

เพื่อตอบสนองต่อความคิดเห็นของ StarWeaver เพื่อให้ทราบถึงสิ่งที่ CPU ต้องทำเพื่อดำเนินการคำสั่งเดียว:

ลองคิดอะไรง่าย ๆ อย่างMOV AX,[SI+10]ที่เราคิดว่า "โหลดขวานพร้อมกับคำที่ SI บวก 10" CPU จะต้อง:

  1. ปล่อยเนื้อหาของพีซี ("โปรแกรมเคาน์เตอร์ลงทะเบียน") ไปยังที่อยู่บัส
  2. อ่าน opcode คำแนะนำจาก data บัส;
  3. พีซีที่เพิ่มขึ้น;
  4. ถอดรหัส opcode เพื่อคิดว่าจะทำอย่างไรกับมัน
  5. ปล่อยเนื้อหาของพีซีไปยังบัสแอดเดรส
  6. อ่านตัวถูกดำเนินการคำสั่ง (ในกรณีนี้ 10) จากบัสข้อมูล
  7. พีซีที่เพิ่มขึ้น;
  8. ป้อนตัวถูกดำเนินการและ SI ไปยัง adder
  9. ปล่อยผลลัพธ์ของ adder ไปยังแอดเดรสบัส
  10. อ่าน AX จากดาต้าบัส

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

ตอนนี้ให้พิจารณาว่ามีโหมดการกำหนดแอดเดรสที่ซับซ้อนเช่นMOV AX, [DX+SI*4+10]และคำแนะนำที่ซับซ้อนยิ่งขึ้นเช่นเดียวกับMUL AX, operandที่ใช้ลูปภายใน CPU เพื่อคำนวณผลลัพธ์

ดังนั้นจุดของฉันที่นี่คือคำอุปมา "ระดับอะตอม" นั้นไม่เหมาะสมสำหรับระดับการเรียนการสอนของ CPU อาจเหมาะสำหรับระดับขั้นตอนไปป์ไลน์หากคุณไม่ต้องการลงไปจนถึงระดับประตูตรรกะจริงเกินไป


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

1
@StarWeaver ฉันชอบความคิดเห็นของคุณดังนั้นฉันจึงแก้ไขคำตอบเพื่อแก้ไข
Mike Nakis

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

มันคุ้มค่าที่แบริ่งในใจว่าคำถามกองมากเกินการเชื่อมโยงไปโดย OP - หนึ่ง 1.3 ล้านวิวที่น่าจะนำมาใช้กว่า 1 ล้านโปรแกรมเมอร์กับความเป็นจริงที่ไม่คุ้นเคยก่อนหน้านี้ว่า "สาขาทำนาย" แม้จะมีอยู่ - การจัดแสดงนิทรรศการตัวอย่างเช่นในJava สำหรับคนอย่างฉันที่คุ้นเคยกับการทำงานในระดับที่เป็นนามธรรมซึ่งภาษาอย่าง Java ให้เราแม้MOV AX,[SI+10]จะเป็นคนต่างด้าวไม่ใช่ "วิ" โปรแกรมเมอร์ส่วนใหญ่ทุกวันนี้ไม่เคยเขียนชุดประกอบ เราไม่ "คิดอย่างไร้เดียงสา" ว่ามันหมายถึงอะไร
Mark Amery

@ MarkAmery ดีเอาล่ะฉันคิดว่ามันค่อนข้างชัดเจนว่าโดย "เรามนุษย์" ฉันหมายถึง "เรามนุษย์ที่กล้าเขียนชุมนุม" ประเด็นที่ต้องทำคือแม้แต่โปรแกรมเมอร์ภาษาแอสเซมบลีก็ไม่ได้คิดถึงท่อส่งน้ำตลอดเวลาหรือแม้แต่ในทุกกรณี
Mike Nakis

28

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

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


2
คำอธิบายนี้เรียบร้อย
sharptooth

2

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

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

แต่ที่สำคัญคือซีพียูเริ่มทำงานให้กับกิ่งก้านสาขาที่คาดการณ์ไว้เพราะยังไม่สามารถประเมินสภาพได้เอง


1

แบบสั้น:

ซีพียูบางตัวสามารถเริ่มทำงานกับคำสั่งใหม่ก่อนที่จะจบเก่า นี่คือซีพียูที่ใช้การคาดคะเนสาขา

ตัวอย่าง pseudocode:

int globalVariable;
int Read(int* readThis, int* readThat)
{
    if ((globalVariable*globalVariable % 17) < 5)
       return *readThis;
    else
       return *readThat;
}

ดังกล่าวข้างต้นการตรวจสอบรหัสเงื่อนไขและขึ้นอยู่กับผลที่จะต้องกลับมาอย่างใดอย่างหนึ่งค่าที่เก็บไว้ในหน่วยความจำตำแหน่งหรือค่าที่เก็บไว้ที่addThis readThatหากการคาดคะเนสาขาคาดการณ์ว่าเงื่อนไขจะเป็นtrueเช่นนั้น CPU จะอ่านค่าที่เก็บไว้ที่ตำแหน่งหน่วยความจำแล้วaddThisทำการคำนวณที่จำเป็นเพื่อประเมินifคำสั่งนั้น นี่คือตัวอย่างที่ง่าย


1

ใช่เงื่อนไขจะถูกตรวจสอบอย่างใดอย่างหนึ่ง แต่ข้อดีของการพยากรณ์สาขาคือคุณสามารถทำงานได้แทนที่จะรอผลการตรวจสภาพ

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

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

Modern CPUs ไม่ทำงานส่วนใหญ่เนื่องจากกำลังรอการตอบสนองจาก IO หรือผลลัพธ์ของการคำนวณอื่น ๆ เวลานี้สามารถใช้ในการทำงานในอนาคต

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

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