คำแนะนำต่อไปนี้ทั้งหมดทำสิ่งเดียวกัน: ตั้งค่า%eax
เป็นศูนย์ วิธีใดเหมาะสมที่สุด (ต้องใช้รอบเครื่องน้อยที่สุด)
xorl %eax, %eax
mov $0, %eax
andl $0, %eax
คำแนะนำต่อไปนี้ทั้งหมดทำสิ่งเดียวกัน: ตั้งค่า%eax
เป็นศูนย์ วิธีใดเหมาะสมที่สุด (ต้องใช้รอบเครื่องน้อยที่สุด)
xorl %eax, %eax
mov $0, %eax
andl $0, %eax
คำตอบ:
TL; DR สรุป : xor same, same
เป็นทางเลือกที่ดีที่สุดสำหรับซีพียูทั้งหมด ไม่มีวิธีอื่นใดที่มีข้อได้เปรียบเหนือกว่าวิธีนี้และอย่างน้อยก็มีข้อได้เปรียบเหนือวิธีอื่นใด แนะนำอย่างเป็นทางการโดย Intel และ AMD และสิ่งที่คอมไพเลอร์ทำ ในโหมด 64 บิตยังคงใช้xor r32, r32
เพราะการเขียนแบบ 32 บิตศูนย์ reg บน 32 xor r64, r64
เป็นการเสียไบต์เพราะต้องการคำนำหน้า REX
ที่แย่ไปกว่านั้น Silvermont ยอมรับxor r32,r32
ว่าเป็นการทำลายล้างเท่านั้นไม่ใช่ขนาดตัวถูกดำเนินการ 64 บิต ดังนั้นแม้ว่าจะต้องใช้คำนำหน้า REX เนื่องจากคุณเป็นศูนย์ r8..r15 ให้ใช้xor r10d,r10d
ไม่ใช่xor r10,r10
.
ตัวอย่างจำนวนเต็ม GP:
xor eax, eax ; RAX = 0. Including AL=0 etc.
xor r10d, r10d ; R10 = 0
xor edx, edx ; RDX = 0
; small code-size alternative: cdq ; zero RDX if EAX is already zero
; SUB-OPTIMAL
xor rax,rax ; waste of a REX prefix, and extra slow on Silvermont
xor r10,r10 ; bad on Silvermont (not dep breaking), same as r10d everywhere else because a REX prefix is still needed for r10d or r10.
mov eax, 0 ; doesn't touch FLAGS, but not faster and takes more bytes
and eax, 0 ; false dependency. (Microbenchmark experiments might want this)
sub eax, eax ; same as xor on most but not all CPUs; bad on Silvermont for example.
xor al, al ; false dep on some CPUs, not a zeroing idiom. Use xor eax,eax
mov al, 0 ; only 2 bytes, and probably better than xor al,al *if* you need to leave the rest of EAX/RAX unmodified
Zeroing pxor xmm, xmm
ลงทะเบียนเวกเตอร์ที่ดีที่สุดมักจะทำด้วย โดยทั่วไปแล้วนั่นคือสิ่งที่ gcc ทำ (ก่อนใช้ด้วยคำแนะนำ FP)
xorps xmm, xmm
สามารถทำให้รู้สึก สั้นกว่าหนึ่งไบต์pxor
แต่xorps
ต้องการพอร์ตการดำเนินการ 5 บน Intel Nehalem ในขณะที่pxor
สามารถทำงานบนพอร์ตใดก็ได้ (0/1/5) (โดยปกติแล้วเวลาในการตอบสนองการหน่วงเวลาบายพาส 2c ของ Nehalem ระหว่างจำนวนเต็มและ FP จะไม่เกี่ยวข้องเนื่องจากการดำเนินการที่ไม่อยู่ในใบสั่งมักจะซ่อนไว้ที่จุดเริ่มต้นของห่วงโซ่การพึ่งพาใหม่)
สำหรับสถาปัตยกรรมขนาดเล็กตระกูล SnB ทั้งรสชาติของ xor-zeroing ไม่จำเป็นต้องมีพอร์ตการประมวลผล บน AMD และ pre-Nehalem P6 / Core2 Intel xorps
และpxor
ได้รับการจัดการในลักษณะเดียวกัน (ตามคำแนะนำเวกเตอร์จำนวนเต็ม)
การใช้คำสั่งเวกเตอร์ 128b เวอร์ชัน AVX จะเป็นศูนย์ที่ส่วนบนของ reg เช่นกันดังนั้นจึงvpxor xmm, xmm, xmm
เป็นทางเลือกที่ดีสำหรับการทำให้ YMM เป็นศูนย์ (AVX1 / AVX2) หรือ ZMM (AVX512) หรือส่วนขยายเวกเตอร์ในอนาคต vpxor ymm, ymm, ymm
ไม่ใช้ไบต์พิเศษใด ๆ ในการเข้ารหัสแม้ว่าจะทำงานแบบเดียวกันบน Intel แต่ช้ากว่าบน AMD ก่อน Zen2 (2 uops) การศูนย์ AVX512 ZMM จะต้องใช้ไบต์พิเศษ (สำหรับคำนำหน้า EVEX) ดังนั้นจึงควรเลือกค่าศูนย์ XMM หรือ YMM
ตัวอย่าง XMM / YMM / ZMM
# Good:
xorps xmm0, xmm0 ; smallest code size (for non-AVX)
pxor xmm0, xmm0 ; costs an extra byte, runs on any port on Nehalem.
xorps xmm15, xmm15 ; Needs a REX prefix but that's unavoidable if you need to use high registers without AVX. Code-size is the only penalty.
# Good with AVX:
vpxor xmm0, xmm0, xmm0 ; zeros X/Y/ZMM0
vpxor xmm15, xmm0, xmm0 ; zeros X/Y/ZMM15, still only 2-byte VEX prefix
#sub-optimal AVX
vpxor xmm15, xmm15, xmm15 ; 3-byte VEX prefix because of high source reg
vpxor ymm0, ymm0, ymm0 ; decodes to 2 uops on AMD before Zen2
# Good with AVX512
vpxor xmm15, xmm0, xmm0 ; zero ZMM15 using an AVX1-encoded instruction (2-byte VEX prefix).
vpxord xmm30, xmm30, xmm30 ; EVEX is unavoidable when zeroing zmm16..31, but still prefer XMM or YMM for fewer uops on probable future AMD. May be worth using only high regs to avoid needing vzeroupper in short functions.
# Good with AVX512 *without* AVX512VL (e.g. KNL / Xeon Phi)
vpxord zmm30, zmm30, zmm30 ; Without AVX512VL you have to use a 512-bit instruction.
# sub-optimal with AVX512 (even without AVX512VL)
vpxord zmm0, zmm0, zmm0 ; EVEX prefix (4 bytes), and a 512-bit uop. Use AVX1 vpxor xmm0, xmm0, xmm0 even on KNL to save code size.
ดูvxorps-zeroing บน AMD Jaguar / Bulldozer / Zen เร็วกว่าด้วยการลงทะเบียน xmm มากกว่า ymm หรือไม่ และ
วิธีใดที่มีประสิทธิภาพที่สุดในการล้างการลงทะเบียน ZMM เพียงตัวเดียวหรือสองสามตัวบน Knights Landing
กึ่งเกี่ยวข้อง: วิธีที่เร็วที่สุดในการตั้งค่า __m256 ให้เป็นหนึ่งบิต
ทั้งหมดและตั้งค่าบิตทั้งหมดในทะเบียน CPU เป็น 1 อย่างมีประสิทธิภาพยังครอบคลุมการk0..7
ลงทะเบียนมาสก์AVX512 ด้วย SSE / AVX vpcmpeqd
กำลังทำลายล้างในหลาย ๆ เรื่อง (แม้ว่าจะยังต้องการ uop ในการเขียน 1s) แต่ AVX512 vpternlogd
สำหรับ ZMM regs ก็ไม่ได้ทำลาย ภายในลูปให้พิจารณาคัดลอกจากรีจิสเตอร์อื่นแทนที่จะสร้างใหม่ด้วย ALU uop โดยเฉพาะอย่างยิ่งกับ AVX512
แต่การเป็นศูนย์มีราคาถูก: การ xor-zeroing xmm reg ภายในลูปมักจะดีพอ ๆ กับการคัดลอกยกเว้นซีพียู AMD บางรุ่น (Bulldozer และ Zen) ซึ่งมีการกำจัดการเคลื่อนย้ายสำหรับ vector regs แต่ยังต้องใช้ ALU uop เพื่อเขียนเลขศูนย์สำหรับ xor -zeroing
ซีพียูบางคนรับรู้sub same,same
ว่าเป็นสำนวน zeroing เหมือนxor
แต่ซีพียูทั้งหมดที่รู้จักสำนวน zeroing xor
ใดรู้จัก เพียงแค่ใช้xor
เพื่อให้คุณไม่ต้องกังวลว่า CPU ตัวใดจะจำสำนวนที่เป็นศูนย์ได้
xor
(เป็นสำนวนการเป็นศูนย์ที่ได้รับการยอมรับซึ่งแตกต่างจากmov reg, 0
) มีข้อดีบางประการที่ชัดเจนและลึกซึ้ง (รายการสรุปแล้วฉันจะขยายในสิ่งเหล่านั้น):
mov reg,0
. (ซีพียูทั้งหมด)ขนาดรหัสเครื่องที่เล็กกว่า (2 ไบต์แทนที่จะเป็น 5) เป็นข้อดีเสมอ: ความหนาแน่นของโค้ดที่สูงขึ้นทำให้พลาดแคชคำสั่งน้อยลงและดึงคำสั่งได้ดีขึ้นและอาจถอดรหัสแบนด์วิดท์ได้
ประโยชน์ของการไม่ใช้หน่วยประมวลผลสำหรับ xor บน microarchitectures ตระกูล Intel SnB นั้นมีน้อย แต่ช่วยประหยัดพลังงาน มีแนวโน้มที่จะมีความสำคัญกับ SnB หรือ IvB ซึ่งมีพอร์ตการดำเนินการ ALU เพียง 3 พอร์ต Haswell และใหม่กว่ามีพอร์ตการดำเนินการ 4 พอร์ตที่สามารถจัดการคำสั่ง ALU จำนวนเต็มซึ่งรวมถึงmov r32, imm32
ด้วยการตัดสินใจที่สมบูรณ์แบบโดยตัวกำหนดตารางเวลา (ซึ่งไม่ได้เกิดขึ้นในทางปฏิบัติเสมอไป) HSW ยังคงรักษาได้ 4 uops ต่อนาฬิกาแม้ว่าพวกเขาทั้งหมดจะต้องการ ALU ก็ตาม พอร์ตการดำเนินการ
ดูคำตอบของฉันสำหรับคำถามอื่นเกี่ยวกับการลงทะเบียนเป็นศูนย์สำหรับรายละเอียดเพิ่มเติม
บล็อกโพสต์ของ Bruce Dawsonที่ Michael Petch เชื่อมโยง (ในความคิดเห็นเกี่ยวกับคำถาม) ชี้ให้เห็นว่าxor
ได้รับการจัดการในขั้นตอนการเปลี่ยนชื่อโดยไม่ต้องใช้หน่วยดำเนินการ (ศูนย์ uops ในโดเมนที่ไม่ได้ใช้) แต่พลาดความจริงที่ว่ามันยังคงเป็นหนึ่งใน uop ในโดเมนที่หลอมรวม ซีพียู Intel สมัยใหม่สามารถออกและเลิกใช้งาน fused-domain ได้ 4 ครั้งต่อนาฬิกา นั่นคือจุดที่ 4 ศูนย์ต่อนาฬิกา จำกัด มาจาก ความซับซ้อนที่เพิ่มขึ้นของฮาร์ดแวร์การเปลี่ยนชื่อการลงทะเบียนเป็นเพียงหนึ่งในสาเหตุของการจำกัดความกว้างของการออกแบบเป็น 4 (บรูซเขียนบล็อกโพสต์ที่ยอดเยี่ยมมากเช่นซีรี่ส์ของเขาเกี่ยวกับคณิตศาสตร์ FP และ x87 / SSE / ปัญหาการปัดเศษซึ่งฉันทำ ขอเเนะนำ).
เกี่ยวกับเอเอ็มดีซีพียู Bulldozer ครอบครัว , mov immediate
วิ่งบนเดียวกัน EX0 / EX1 xor
พอร์ตการดำเนินการเป็นจำนวนเต็ม mov reg,reg
ยังสามารถรันบน AGU0 / 1 ได้ แต่สำหรับการลงทะเบียนคัดลอกเท่านั้นไม่ใช่สำหรับการตั้งค่าจากทันที ดังนั้น AFAIK ในเอเอ็มดีได้เปรียบเพียง แต่จะxor
มากกว่าmov
คือการเข้ารหัสสั้น นอกจากนี้ยังอาจช่วยประหยัดทรัพยากรการลงทะเบียนทางกายภาพ แต่ฉันไม่เห็นการทดสอบใด ๆ
สำนวนการเป็นศูนย์ที่ได้รับการยอมรับจะหลีกเลี่ยงบทลงโทษการลงทะเบียนบางส่วนในซีพียู Intel ซึ่งเปลี่ยนชื่อการลงทะเบียนบางส่วนแยกจากการลงทะเบียนแบบเต็ม (ตระกูล P6 และ SnB)
xor
จะแท็กรีจิสเตอร์ว่ามีส่วนบนเป็นศูนย์ดังนั้นxor eax, eax
/ inc al
/ inc eax
หลีกเลี่ยงบทลงโทษการลงทะเบียนบางส่วนตามปกติที่ซีพียู pre-IvB มี แม้ว่าจะไม่มีxor
IvB ก็ต้องการการผสานรวมเมื่อมีการแก้ไข 8 บิตสูง ( AH
) จากนั้นจึงอ่านรีจิสเตอร์ทั้งหมดและแฮสก็ลบออกด้วยซ้ำ
จากคู่มือ microarch ของ Agner Fog หน้า 98 (ส่วน Pentium M อ้างอิงโดยส่วนต่อมารวมถึง SnB):
โปรเซสเซอร์รับรู้ XOR ของรีจิสเตอร์โดยตั้งค่าเป็นศูนย์ แท็กพิเศษในรีจิสเตอร์จำได้ว่าส่วนสูงของรีจิสเตอร์เป็นศูนย์เพื่อให้ EAX = AL แท็กนี้จำได้แม้จะวนซ้ำ:
; Example 7.9. Partial register problem avoided in loop xor eax, eax mov ecx, 100 LL: mov al, [esi] mov [edi], eax ; No extra uop inc esi add edi, 4 dec ecx jnz LL
(จาก pg82): โปรเซสเซอร์จะจำว่า EAX 24 บิตด้านบนเป็นศูนย์ตราบเท่าที่คุณไม่ได้รับการขัดจังหวะการคาดเดาผิดหรือเหตุการณ์การจัดลำดับอื่น ๆ
pg82 ของคู่มือที่ยังยืนยันว่าmov reg, 0
จะไม่ได้รับการยอมรับเป็นสำนวน zeroing อย่างน้อยในช่วงต้น P6 ออกแบบเช่น PIII หรือ PM ฉันจะแปลกใจมากถ้าพวกเขาใช้ทรานซิสเตอร์ในการตรวจจับมันในซีพียูรุ่นหลัง ๆ
xor
ตั้งค่าสถานะซึ่งหมายความว่าคุณต้องระมัดระวังในการทดสอบเงื่อนไข เนื่องจากsetcc
น่าเสียดายที่มีให้เฉพาะกับปลายทาง 8 บิตคุณจึงต้องระมัดระวังเพื่อหลีกเลี่ยงบทลงโทษในการลงทะเบียนบางส่วน
คงจะดีถ้า x86-64 เปลี่ยนหนึ่งใน opcodes ที่ถูกลบ (เช่น AAM) สำหรับ 16/32/64 บิตsetcc r/m
โดยมีการเข้ารหัสเพรดิเคตในฟิลด์ 3 บิตที่ลงทะเบียนต้นทางของฟิลด์ r / m (ทาง คำแนะนำตัวถูกดำเนินการเดี่ยวอื่น ๆ ใช้เป็นบิต opcode) แต่พวกเขาไม่ได้ทำอย่างนั้นและนั่นก็ไม่ช่วยสำหรับ x86-32 อยู่ดี
ตามหลักการแล้วคุณควรใช้xor
/ ตั้งค่าสถานะ / setcc
/ อ่านทะเบียนแบบเต็ม:
...
call some_func
xor ecx,ecx ; zero *before* the test
test eax,eax
setnz cl ; cl = (some_func() != 0)
add ebx, ecx ; no partial-register penalty here
สิ่งนี้มีประสิทธิภาพที่ดีที่สุดสำหรับซีพียูทั้งหมด (ไม่มีการหยุดชะงักการรวม uops หรือการอ้างอิงเท็จ)
สิ่งที่มีความซับซ้อนมากขึ้นเมื่อคุณไม่ต้องการที่จะ xor ก่อนการเรียนการสอนธงการตั้งค่า เช่นคุณต้องการแยกเงื่อนไขหนึ่งแล้ว setcc กับเงื่อนไขอื่นจากแฟล็กเดียวกัน เช่นcmp/jle
, sete
และคุณอย่างใดอย่างหนึ่งไม่ได้มีการลงทะเบียนอะไหล่หรือคุณต้องการที่จะให้xor
ออกจากเส้นทางรหัสไม่ได้นำมารวมกัน
ไม่มีสำนวนการเป็นศูนย์ที่เป็นที่รู้จักซึ่งไม่มีผลต่อแฟล็กดังนั้นทางเลือกที่ดีที่สุดจึงขึ้นอยู่กับสถาปัตยกรรมขนาดเล็กเป้าหมาย บน Core2 การใส่ uop แบบผสานอาจทำให้เกิดวงจร 2 หรือ 3 รอบ ดูเหมือนว่าจะถูกกว่าใน SnB แต่ฉันไม่ได้ใช้เวลาในการวัดมากนัก การใช้mov reg, 0
/ setcc
จะมีโทษอย่างมีนัยสำคัญสำหรับซีพียู Intel รุ่นเก่าและยังค่อนข้างแย่กว่า Intel รุ่นใหม่
การใช้setcc
/ movzx r32, r8
อาจเป็นทางเลือกที่ดีที่สุดสำหรับตระกูล Intel P6 และ SnB หากคุณไม่สามารถ xor-zero ก่อนหน้าคำสั่งการตั้งค่าสถานะ ควรจะดีกว่าการทดสอบซ้ำหลังจาก xor-zeroing (อย่าพิจารณาsahf
/ lahf
หรือpushf
/ popf
) IvB สามารถกำจัดได้movzx r32, r8
(เช่นจัดการด้วยการเปลี่ยนชื่อการลงทะเบียนโดยไม่มีหน่วยประมวลผลหรือเวลาแฝงเช่น xor-zeroing) Haswell และใหม่กว่ากำจัดเฉพาะmov
คำสั่งปกติดังนั้นจึงmovzx
ใช้หน่วยประมวลผลและมีเวลาแฝงที่ไม่ใช่ศูนย์ทำให้การทดสอบ / setcc
/ movzx
แย่กว่าxor
/ ทดสอบ / setcc
แต่อย่างน้อยก็ยังดีพอ ๆ กับการทดสอบ / mov r,0
/ setcc
(และดีกว่ามากสำหรับซีพียูรุ่นเก่า)
การใช้setcc
/ movzx
โดยไม่มีศูนย์ก่อนนั้นไม่ดีใน AMD / P4 / Silvermont เนื่องจากไม่ได้ติดตาม deps แยกต่างหากสำหรับการลงทะเบียนย่อย จะมีการลบค่าเก่าของทะเบียนเป็นเท็จ การใช้mov reg, 0
/ setcc
สำหรับการเป็นศูนย์ / การทำลายการพึ่งพาอาจเป็นทางเลือกที่ดีที่สุดเมื่อxor
/ ทดสอบ / setcc
ไม่ใช่ตัวเลือก
แน่นอนว่าถ้าคุณไม่ต้องการsetcc
ให้เอาต์พุตกว้างเกิน 8 บิตคุณก็ไม่จำเป็นต้องศูนย์อะไรเลย อย่างไรก็ตามโปรดระวังการอ้างอิงที่ผิดพลาดบน CPU นอกเหนือจาก P6 / SnB หากคุณเลือกรีจิสเตอร์ที่เพิ่งเป็นส่วนหนึ่งของห่วงโซ่การพึ่งพาที่ยาวนาน (และระวังการก่อให้เกิด reg Stall บางส่วนหรือ uop พิเศษหากคุณเรียกใช้ฟังก์ชันที่อาจบันทึก / กู้คืนรีจิสเตอร์ที่คุณใช้เป็นส่วนหนึ่ง)
and
การมีศูนย์ในทันทีไม่ได้ถูกระบุไว้เป็นพิเศษเนื่องจากไม่ขึ้นกับค่าเก่าของซีพียูใด ๆ ที่ฉันรู้จักดังนั้นจึงไม่ทำลายห่วงโซ่การพึ่งพา มันไม่มีข้อดีกว่าxor
และข้อเสียมากมาย
มีประโยชน์สำหรับการเขียน microbenchmarks เมื่อคุณต้องการการอ้างอิงเป็นส่วนหนึ่งของการทดสอบเวลาในการตอบสนอง แต่ต้องการสร้างค่าที่ทราบโดยการกำหนดค่าเป็นศูนย์และเพิ่ม
โปรดดูhttp://agner.org/optimize/สำหรับรายละเอียด microarchซึ่งรวมถึงสำนวนการเป็นศูนย์ที่ได้รับการยอมรับว่าเป็นการทำลายการพึ่งพา (เช่นใช้sub same,same
กับ CPU บางตัว แต่ไม่ใช่ทั้งหมดในขณะที่ระบบxor same,same
รู้จักทั้งหมด) mov
จะทำลายห่วงโซ่การพึ่งพาของค่าเดิม ของรีจิสเตอร์ (ไม่ว่าค่าต้นทางจะเป็นศูนย์หรือไม่ก็ตามเพราะนั่นคือวิธีการmov
ทำงาน) xor
เพียง แต่แบ่งโซ่พึ่งพาในกรณีพิเศษที่ src และปลายทางมีการลงทะเบียนเดียวกันซึ่งเป็นเหตุผลที่mov
ถูกปล่อยออกมาจากรายการพิเศษได้รับการยอมรับการพึ่งพาเบรกเกอร์ (นอกจากนี้เนื่องจากไม่ได้รับการยอมรับว่าเป็นสำนวนที่เป็นศูนย์รวมทั้งประโยชน์อื่น ๆ ที่มี)
ที่น่าสนใจคือการออกแบบ P6 ที่เก่าแก่ที่สุด (PPro ถึง Pentium III) ไม่รู้จักxor
-zeroing เป็นตัวตัดการพึ่งพา แต่เป็นสำนวนที่เป็นศูนย์เพื่อวัตถุประสงค์ในการหลีกเลี่ยงแผงขายของที่ลงทะเบียนบางส่วนดังนั้นในบางกรณีจึงควรใช้ทั้งสองอย่าง mov
แล้วxor
-zeroing ในลำดับนั้นเพื่อทำลาย dep แล้วศูนย์อีกครั้ง + ตั้งค่าบิตแท็กภายในที่บิตสูงเป็นศูนย์ดังนั้น EAX = AX = AL
ดูตัวอย่างของ Agner Fog 6.17 ใน microarch pdf ของเขา เขาบอกว่าสิ่งนี้ใช้ได้กับ P2, P3 และแม้กระทั่ง (ช่วงต้น?) PM ความคิดเห็นในบล็อกโพสต์ที่เชื่อมโยงบอกว่าเป็น PPro เท่านั้นที่มีการกำกับดูแลนี้ แต่ฉันได้ทดสอบ Katmai PIII และ @Fanael ทดสอบกับ Pentium M และเราทั้งคู่พบว่ามันไม่ได้ทำลายการพึ่งพาสำหรับเวลาแฝง - imul
โซ่ขา นี่เป็นการยืนยันผลลัพธ์ของ Agner Fog อย่างน่าเสียดาย
ถ้ามันทำให้โค้ดของคุณดีขึ้นจริง ๆ หรือบันทึกคำแนะนำให้แน่ใจว่าให้ศูนย์mov
เพื่อหลีกเลี่ยงการสัมผัสแฟล็กตราบใดที่คุณไม่แนะนำปัญหาด้านประสิทธิภาพนอกเหนือจากขนาดโค้ด การหลีกเลี่ยงแฟล็ก clobbering เป็นเหตุผลเดียวที่สมเหตุสมผลสำหรับการไม่ใช้xor
แต่บางครั้งคุณสามารถ xor-zero ก่อนสิ่งที่กำหนดแฟล็กได้หากคุณมีทะเบียนสำรอง
mov
-zero ข้างหน้าsetcc
จะดีกว่าสำหรับเวลาแฝงmovzx reg32, reg8
(ยกเว้นใน Intel เมื่อคุณสามารถเลือกรีจิสเตอร์ที่แตกต่างกันได้) แต่ขนาดโค้ดแย่ลง
mov reg, src
ยังแบ่งโซ่การใช้งานสำหรับซีพียู OO (ไม่ว่า src จะเป็น imm32 [mem]
หรือรีจิสเตอร์อื่นก็ตาม) การทำลายการพึ่งพานี้ไม่ได้รับการกล่าวถึงในคู่มือการเพิ่มประสิทธิภาพเนื่องจากไม่ใช่กรณีพิเศษที่เกิดขึ้นเฉพาะเมื่อ src และ dest เป็นรีจิสเตอร์เดียวกัน มันเกิดขึ้นเสมอสำหรับคำแนะนำที่ไม่ขึ้นอยู่กับปลายทางของพวกเขา (ยกเว้นการนำไปใช้ของ Intel ในการกำหนดpopcnt/lzcnt/tzcnt
เป้าหมายที่ผิดพลาด)
mov
ฟรีมีเวลาแฝงเป็นศูนย์เท่านั้น ส่วน "ไม่ใช้พอร์ตการดำเนินการ" มักจะไม่สำคัญ ปริมาณงาน Fused-domain อาจเป็นปัญหาคอขวดได้อย่างง่ายดาย กับโหลดหรือร้านค้าในการผสมผสาน
xor r64, r64
ไม่เพียงแค่เสียไบต์ อย่างที่คุณบอกว่าxor r32, r32
เป็นทางเลือกที่ดีที่สุดโดยเฉพาะกับ KNL ดูส่วนที่ 15.7 "กรณีพิเศษเพื่อความเป็นอิสระ" ในคู่มือไมโครชั้นนี้หากคุณต้องการอ่านเพิ่มเติม