กลับไปหน้าบทความ

อ่าน 4 นาที

การแยกแยะความจำ

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

การแยกแยะความจำ

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

พื้นหลัง

การพึ่งพา

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

1: บวก $1, $2, $3 # R1 <= R2 + R3 2: เพิ่ม $5, $1, $4 # R5 <= R1 + R4 (ขึ้นอยู่กับ 1) 

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

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

1: เก็บ $1, 2($2) # Mem[R2+2] <= R1 2: โหลด $3, 4($4) # R3 <= Mem[R4+4] (อาจขึ้นอยู่กับ 1 อาจเป็นที่อยู่เดียวกันกับข้างต้น) 

ในที่นี้ คำสั่ง store จะเขียนค่าลงในตำแหน่งหน่วยความจำที่ระบุโดยค่าในแอดเดรส (R2+2) และคำสั่ง load จะอ่านค่าที่ตำแหน่งหน่วยความจำที่ระบุโดยค่าในแอดเดรส (R4+4) ไมโครโปรเซสเซอร์ไม่สามารถตรวจสอบล่วงหน้าได้ว่าตำแหน่งหน่วยความจำที่ระบุในสองคำสั่งนี้แตกต่างกันหรือเป็นตำแหน่งเดียวกัน เนื่องจากตำแหน่งขึ้นอยู่กับค่าใน R2 และ R4 หากตำแหน่งแตกต่างกัน คำสั่งทั้งสองจะทำงานได้อย่างอิสระและสามารถดำเนินการได้สำเร็จแม้จะไม่เรียงลำดับก็ตาม อย่างไรก็ตาม หากตำแหน่งเหมือนกัน คำสั่ง load จะขึ้นอยู่กับคำสั่ง store ในการสร้างค่า ซึ่งเรียกว่าการพึ่งพาที่ไม่ชัดเจน (ambiguous dependence )

การดำเนินการนอกลำดับและการเข้าถึงหน่วยความจำ

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

1: mul $27, $27, $20 2: sw $27, 0($30) 3: lw $08, 0($31) 4: sw $26, 0($30) 5: lw $09, 0($31) 

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

ในสถานการณ์นี้sw $27, 0($30)คำสั่งในบรรทัดที่ 2 ยังไม่พร้อมที่จะดำเนินการ แต่lw $08, 0($31)คำสั่งในบรรทัดที่ 3 พร้อมแล้ว หากโปรเซสเซอร์อนุญาตให้lwคำสั่งนั้นดำเนินการก่อนคำสั่งsw`load` คำสั่ง `store` จะอ่านค่าเก่าจากระบบหน่วยความจำ แต่ควรจะอ่านค่าที่เพิ่งเขียนลงไปโดยคำสั่ง `store` swคำสั่ง `load` และ `store` ถูกดำเนินการนอกลำดับของโปรแกรม แต่มีความสัมพันธ์ระหว่างหน่วยความจำที่ถูกละเมิด

ในทำนองเดียวกัน สมมติว่ารีจิสเตอร์$26พร้อมใช้งานแล้วsw $26, 0($30)คำสั่งในบรรทัดที่ 4 ก็พร้อมที่จะดำเนินการเช่นกัน และอาจดำเนินการก่อนคำสั่งก่อนหน้าlw $08, 0($31)ในบรรทัดที่ 3 หากเกิดกรณีนี้lw $08, 0($31)คำสั่งจะอ่าน ค่า ที่ไม่ถูกต้องจากระบบหน่วยความจำ เนื่องจากคำสั่งจัดเก็บข้อมูลในภายหลังได้เขียนค่าลงไปก่อนที่คำสั่งโหลดจะดำเนินการ

การกำหนดลักษณะการพึ่งพาของหน่วยความจำ

การพึ่งพาหน่วยความจำมีอยู่ 3 รูปแบบ:

  • การพึ่งพาแบบ อ่านหลังจากเขียน (Read-After-Writeหรือ RAW): หรือที่เรียกว่าการพึ่งพาที่แท้จริง การพึ่งพาแบบ RAW เกิดขึ้นเมื่อการดำเนินการโหลดอ่านค่าจากหน่วยความจำที่ถูกสร้างขึ้นโดยการดำเนินการจัดเก็บก่อนหน้าล่าสุดไปยังที่อยู่เดียวกันนั้น
  • การพึ่งพาแบบ Write-After-Read (WAR): หรือที่รู้จักกันในชื่อ การพึ่งพาแบบตรงข้าม (Anti-dependencies) การพึ่งพาแบบ WAR เกิดขึ้นเมื่อการดำเนินการจัดเก็บข้อมูลเขียนค่าลงในหน่วยความจำที่การดำเนินการโหลดก่อนหน้าได้อ่านค่าไปแล้ว
  • การพึ่งพาแบบ เขียนต่อจากการเขียน (Write-After-Writeหรือ WAW): หรือที่เรียกว่าการพึ่งพาเอาต์พุต การพึ่งพาแบบ WAW เกิดขึ้นเมื่อการดำเนินการจัดเก็บข้อมูลสองครั้งเขียนค่าไปยังที่อยู่หน่วยความจำเดียวกัน

ความสัมพันธ์ทั้งสามอย่างแสดงไว้ในส่วนของโค้ดด้านบน (คัดลอกมาเพื่อให้เข้าใจง่ายขึ้น):

1: div $27, $20 2: sw $27, 0($30) 3: lw $08, 0($31) 4: sw $26, 0($30) 5: lw $09, 0($31) 
  • คำlw $08, 0($31)สั่งในบรรทัดที่ 3 มีการพึ่งพาแบบ RAW กับsw $27, 0($30)คำสั่งในบรรทัดที่ 2 และlw $09, 0($31)คำสั่งในบรรทัดที่ 5 มีการพึ่งพาแบบ RAW กับคำsw $26, 0($30)สั่งในบรรทัดที่ 4 คำสั่งโหลดทั้งสองคำสั่งอ่านที่อยู่หน่วยความจำที่คำสั่งจัดเก็บก่อนหน้าเขียนไว้ คำสั่งจัดเก็บเป็นคำสั่งที่สร้างข้อมูลล่าสุดไปยังที่อยู่หน่วยความจำนั้น และคำสั่งโหลดกำลังอ่านค่าของที่อยู่หน่วยความจำนั้น
  • คำsw $26, 0($30)สั่งในบรรทัดที่ 4 มีการพึ่งพาแบบ WAR กับlw $08, 0($31)คำสั่งในบรรทัดที่ 3 เนื่องจากเป็นการเขียนที่อยู่หน่วยความจำที่คำสั่งโหลดก่อนหน้าอ่านมา
  • คำsw $26, 0($30)สั่งในบรรทัดที่ 4 มีความสัมพันธ์แบบ WAW กับsw $27, 0($30)คำสั่งในบรรทัดที่ 2 เนื่องจากทั้งสองคำสั่งเขียนข้อมูลไปยังที่อยู่หน่วยความจำเดียวกัน

กลไกการแยกแยะความหมายของหน่วยความจำ

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

หลีกเลี่ยงการพึ่งพาไฟล์ WAR และ WAW

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

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

ดังนั้น หากไม่มีการบัฟเฟอร์คำสั่งจัดเก็บ คำสั่งจัดเก็บจะไม่สามารถทำงานได้จนกว่าคำสั่งก่อนหน้าทั้งหมดที่อาจก่อให้เกิดข้อยกเว้นจะทำงานเสร็จสิ้น (และไม่ก่อให้เกิดข้อยกเว้น) และทราบทิศทางการกระโดดข้ามสาขาก่อนหน้าทั้งหมดแล้ว การบังคับให้คำสั่งจัดเก็บรอจนกว่าจะทราบทิศทางการกระโดดข้ามสาขาและข้อยกเว้นจะลดความสามารถในการทำงานแบบไม่เรียงลำดับลงอย่างมาก และจำกัด ILP ( Instruction Level Parallelism ) และประสิทธิภาพ แต่ด้วยการบัฟเฟอร์คำสั่งจัดเก็บ คำสั่งจัดเก็บสามารถทำงานได้ก่อนคำสั่งกระโดดข้ามสาขาที่ก่อให้เกิดข้อยกเว้นหรือไม่ได้รับการแก้ไข โดยจะบัฟเฟอร์ข้อมูลไว้ในคิวคำสั่งจัดเก็บ แต่จะไม่บันทึกค่าจนกว่าจะเสร็จสิ้นกระบวนการ ซึ่งจะป้องกันไม่ให้คำสั่งจัดเก็บในเส้นทางที่คาดการณ์ผิดพลาดหรือเส้นทางที่ไม่ดีบันทึกค่าลงในระบบหน่วยความจำ ในขณะเดียวกันก็ยังคงให้ ILP และประสิทธิภาพที่เพิ่มขึ้นจากการทำงานแบบไม่เรียงลำดับอย่างเต็มรูปแบบของคำสั่งจัดเก็บ

ร้านค้าเพื่อโหลดการส่งต่อ

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

เพื่อแก้ปัญหานี้ โปรเซสเซอร์จึงใช้เทคนิคที่เรียกว่าการส่งต่อข้อมูลจากการจัดเก็บไปยังการโหลดโดยใช้คิวการจัดเก็บ นอกเหนือจากการบัฟเฟอร์ข้อมูลที่จะจัดเก็บจนกว่าจะเสร็จสิ้นแล้ว คิวการจัดเก็บยังมีจุดประสงค์ที่สองคือ การส่งต่อข้อมูลจากการจัดเก็บที่เสร็จสมบูรณ์แล้วแต่ยังไม่เสร็จสิ้น ("in-flight") ไปยังการโหลดในภายหลัง แทนที่จะเป็น คิว FIFO ธรรมดา คิวการจัดเก็บนั้นเป็นหน่วยความจำที่สามารถระบุที่อยู่ ตาม เนื้อหา (Content-Addressable Memory หรือ CAM)ซึ่งค้นหาโดยใช้ที่อยู่หน่วยความจำ เมื่อการโหลดทำงาน มันจะค้นหาคิวการจัดเก็บสำหรับข้อมูลที่กำลังดำเนินการอยู่ไปยังที่อยู่เดียวกันซึ่งอยู่ก่อนหน้าในลำดับโปรแกรม หากมีข้อมูลจัดเก็บที่ตรงกัน การโหลดจะได้รับค่าข้อมูลจากข้อมูลจัดเก็บนั้นแทนที่จะเป็นระบบหน่วยความจำ หากไม่มีข้อมูลจัดเก็บที่ตรงกัน การโหลดจะเข้าถึงระบบหน่วยความจำตามปกติ ข้อมูลจัดเก็บที่ตรงกันก่อนหน้านี้จะต้องเสร็จสิ้นและยืนยันค่าแล้ว เทคนิคนี้ช่วยให้การโหลดได้รับข้อมูลที่ถูกต้องหากข้อมูลจัดเก็บของผู้ผลิตเสร็จสมบูรณ์แล้วแต่ยังไม่เสร็จสิ้น

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

การละเมิดการพึ่งพา RAW

การตรวจจับการละเมิดการพึ่งพา RAW

ซีพียูแบบ out-of-order สมัยใหม่สามารถใช้เทคนิคหลายอย่างในการตรวจจับการละเมิดการพึ่งพาแบบ RAW แต่เทคนิคทั้งหมดจำเป็นต้องติดตามการโหลดที่กำลังดำเนินการอยู่ตั้งแต่การประมวลผลจนถึงการสิ้นสุดการทำงาน เมื่อการโหลดทำงาน มันจะเข้าถึงระบบหน่วยความจำและ/หรือคิวจัดเก็บเพื่อรับค่าข้อมูล จากนั้นที่อยู่และข้อมูลจะถูกบัฟเฟอร์ไว้ในคิวโหลดจนกว่าจะสิ้นสุดการทำงาน คิวโหลดมีโครงสร้างและฟังก์ชันคล้ายกับคิวจัดเก็บ และในความเป็นจริงในบางโปรเซสเซอร์อาจรวมกับคิวจัดเก็บในโครงสร้างเดียวที่เรียกว่าคิวโหลด-จัดเก็บหรือLSQเทคนิคต่อไปนี้ถูกนำมาใช้หรือได้รับการเสนอเพื่อตรวจจับการละเมิดการพึ่งพาแบบ RAW:

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

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

ความชัดเจนเมื่อเกษียณอายุ

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

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

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

การหลีกเลี่ยงการละเมิดการพึ่งพา RAW

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

ตัวเลือกแรก คือการทำให้การโหลดและการจัดเก็บข้อมูลทำงานตามลำดับ ซึ่งจะช่วยหลีกเลี่ยงการพึ่งพาข้อมูลดิบ (RAW dependences) เนื่องจากไม่มีความเป็นไปได้ที่การโหลดจะทำงานก่อนการจัดเก็บข้อมูลของผู้ผลิต (producer store) และได้รับข้อมูลที่ไม่ถูกต้อง อีกทางเลือกหนึ่งคือการแบ่งการโหลดและการจัดเก็บข้อมูลออกเป็นสองการทำงานอย่างมีประสิทธิภาพ ได้แก่ การสร้างที่อยู่และการเข้าถึงแคช ด้วยการทำงานสองอย่างที่แยกจากกันแต่เชื่อมโยงกันนี้ CPU สามารถอนุญาตให้การโหลดและการจัดเก็บข้อมูลเข้าถึงระบบหน่วยความจำได้ก็ต่อเมื่อการโหลดและการจัดเก็บข้อมูลก่อนหน้านี้ทั้งหมดได้รับการสร้างที่อยู่และบัฟเฟอร์ไว้ใน LSQ แล้วเท่านั้น หลังจากสร้างที่อยู่แล้ว จะไม่มีการพึ่งพาที่ไม่ชัดเจนอีกต่อไป เนื่องจากทราบที่อยู่ทั้งหมดแล้ว ดังนั้นการโหลดที่ขึ้นอยู่กันจะไม่ถูกดำเนินการจนกว่าการจัดเก็บข้อมูลที่เกี่ยวข้องจะเสร็จสมบูรณ์ แผนการนี้ยังคงอนุญาตให้มีการ "ไม่เรียงลำดับ" อยู่บ้าง กล่าวคือ การสร้างที่อยู่สำหรับการโหลดและการจัดเก็บข้อมูลที่กำลังดำเนินการอยู่สามารถดำเนินการไม่เรียงลำดับได้ และเมื่อสร้างที่อยู่แล้ว การเข้าถึงแคชสำหรับการโหลดหรือการจัดเก็บข้อมูลแต่ละครั้งสามารถเกิดขึ้นได้ในลำดับใดก็ได้ที่เคารพการพึ่งพาที่แท้จริง (ซึ่งทราบแล้วในขณะนี้)

ประเด็นเพิ่มเติม

การทำนายการพึ่งพาหน่วยความจำ

โปรเซสเซอร์ที่รองรับการประมวลผลการโหลด/จัดเก็บข้อมูลแบบไม่เรียงลำดับอย่างเต็มรูปแบบ สามารถใช้เทคนิคเพิ่มเติมที่เกี่ยวข้องอีกอย่างหนึ่ง เรียกว่าการทำนายความสัมพันธ์ของหน่วยความจำ (memory dependence prediction ) เพื่อพยายามทำนายความสัมพันธ์ที่แท้จริงระหว่างการโหลดและการจัดเก็บข้อมูลก่อนที่จะทราบที่อยู่ของข้อมูลเหล่านั้น ด้วยเทคนิคนี้ โปรเซสเซอร์สามารถป้องกันการโหลดที่คาดว่าจะขึ้นอยู่กับการจัดเก็บข้อมูลที่กำลังดำเนินการอยู่ ก่อนที่การจัดเก็บข้อมูลนั้นจะเสร็จสมบูรณ์ ซึ่งจะช่วยหลีกเลี่ยงการละเมิดความสัมพันธ์แบบ RAW และหลีกเลี่ยงการล้างไปป์ไลน์และการลดประสิทธิภาพที่เกิดขึ้น ดูรายละเอียดเพิ่มเติมได้ในบทความเกี่ยวกับการทำนายความสัมพันธ์ของหน่วยความจำ

ดูเพิ่มเติม

ดึงข้อมูลมาจาก " https://en.wikipedia.org/w/index.php?title=Memory_disambiguation&oldid=1306783042 "

สรุปเนื้อหา

ข้อมูลสำคัญจากบทความ

ข้อมูลสำคัญเกี่ยวกับ การแยกแยะความจำ

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

การพึ่งพา

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

การดำเนินการนอกลำดับและการเข้าถึงหน่วยความจำ

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

กลไกการแยกแยะความหมายของหน่วยความจำ

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