กรณีที่ดีที่สุด 8 รอบกรณีที่เลวร้ายที่สุด 12 รอบ
เนื่องจากมันยังไม่ชัดเจนในคำถามนี้ฉันจึงใช้วิธีนี้ในการคำนวณเวลาแฝงของ Ivy Bridge
วิธีการที่นี่คือการใช้คำสั่งbsr
(สแกนบิตย้อนกลับ) เป็น log2 ของคนยากจน ผลที่ได้ถูกนำมาใช้เป็นดัชนีในตารางกระโดดซึ่งมีรายการสำหรับบิต 0 ถึง 42 ฉันกำลังสมมติว่ากำหนดว่าการดำเนินการกับข้อมูล 64bit เป็นสิ่งจำเป็นโดยปริยายแล้วใช้ของbsr
การเรียนการสอนเป็น OK
ในอินพุตกรณีที่ดีที่สุดรายการ jumptable สามารถแมปbsr
ผลลัพธ์กับขนาดได้โดยตรง เช่นสำหรับอินพุตในช่วง 32-63 bsr
ผลลัพธ์จะเป็น 5 ซึ่งถูกแมปกับขนาด 1 ในกรณีนี้เส้นทางคำสั่งคือ:
Instruction Latency
bsrq 3
jmp 2
movl 1
jmp 2
total 8
ในที่เลวร้ายที่สุดปัจจัยการผลิตกรณีที่bsr
ผลแผนที่จะถึงสองขนาดที่เป็นไปได้เพื่อให้รายการ jumptable ไม่อีกหนึ่งcmp
เพื่อตรวจสอบว่าเข้าเป็น> 10 n เช่นสำหรับอินพุตในช่วง 64-127 bsr
ผลลัพธ์จะเป็น 6 รายการ jumptable ที่สอดคล้องกันจากนั้นตรวจสอบว่าอินพุต> 100 และตั้งค่าขนาดเอาต์พุตให้สอดคล้องกัน
นอกจากนี้สำหรับเส้นทางกรณีที่เลวร้ายที่สุดเรามีคำสั่ง mov เพิ่มเติมเพื่อโหลดค่า 64 บิตทันทีเพื่อใช้ในcmp
ดังนั้นเส้นทางคำแนะนำกรณีที่เลวร้ายที่สุดคือ:
Instruction Latency
bsrq 3
jmp 2
movabsq 1
cmpq 1
ja 2
movl 1
jmp 2
total 12
นี่คือรหัส:
/* Input is loaded in %rdi */
bsrq %rdi, %rax
jmp *jumptable(,%rax,8)
.m0:
movl $0, %ecx
jmp .end
.m0_1:
cmpq $9, %rdi
ja .m1
movl $0, %ecx
jmp .end
.m1:
movl $1, %ecx
jmp .end
.m1_2:
cmpq $99, %rdi
ja .m2
movl $1, %ecx
jmp .end
.m2:
movl $2, %ecx
jmp .end
.m2_3:
cmpq $999, %rdi
ja .m3
movl $2, %ecx
jmp .end
.m3:
movl $3, %ecx
jmp .end
.m3_4:
cmpq $9999, %rdi
ja .m4
movl $3, %ecx
jmp .end
.m4:
movl $4, %ecx
jmp .end
.m4_5:
cmpq $99999, %rdi
ja .m5
movl $4, %ecx
jmp .end
.m5:
movl $5, %ecx
jmp .end
.m5_6:
cmpq $999999, %rdi
ja .m6
movl $5, %ecx
jmp .end
.m6:
movl $6, %ecx
jmp .end
.m6_7:
cmpq $9999999, %rdi
ja .m7
movl $6, %ecx
jmp .end
.m7:
movl $7, %ecx
jmp .end
.m7_8:
cmpq $99999999, %rdi
ja .m8
movl $7, %ecx
jmp .end
.m8:
movl $8, %ecx
jmp .end
.m8_9:
cmpq $999999999, %rdi
ja .m9
movl $8, %ecx
jmp .end
.m9:
movl $9, %ecx
jmp .end
.m9_10:
movabsq $9999999999, %rax
cmpq %rax, %rdi
ja .m10
movl $9, %ecx
jmp .end
.m10:
movl $10, %ecx
jmp .end
.m10_11:
movabsq $99999999999, %rax
cmpq %rax, %rdi
ja .m11
movl $10, %ecx
jmp .end
.m11:
movl $11, %ecx
jmp .end
.m11_12:
movabsq $999999999999, %rax
cmpq %rax, %rdi
ja .m12
movl $11, %ecx
jmp .end
.m12:
movl $12, %ecx
jmp .end
jumptable:
.quad .m0
.quad .m0
.quad .m0
.quad .m0_1
.quad .m1
.quad .m1
.quad .m1_2
.quad .m2
.quad .m2
.quad .m2_3
.quad .m3
.quad .m3
.quad .m3
.quad .m3_4
.quad .m4
.quad .m4
.quad .m4_5
.quad .m5
.quad .m5
.quad .m5_6
.quad .m6
.quad .m6
.quad .m6
.quad .m6_7
.quad .m7
.quad .m7
.quad .m7_8
.quad .m8
.quad .m8
.quad .m8_9
.quad .m9
.quad .m9
.quad .m9
.quad .m9_10
.quad .m10
.quad .m10
.quad .m10_11
.quad .m11
.quad .m11
.quad .m11_12
.quad .m12
.quad .m12
.quad .m12
.end:
/* output is given in %ecx */
นี้ส่วนใหญ่เกิดจากการส่งออกประกอบ GCC สำหรับหลักฐานของแนวคิดรหัส C ที่ผมเขียน หมายเหตุรหัส C ใช้ goto ที่คำนวณได้เพื่อสร้างตารางการกระโดด นอกจากนี้ยังใช้__builtin_clzll()
gcc builtin ซึ่งคอมไพล์กับbsr
คำสั่ง (บวกxor
)
ฉันพิจารณาวิธีแก้ปัญหาหลายอย่างก่อนที่จะมาถึงที่นี่:
FYL2X
เพื่อคำนวณล็อกธรรมชาติจากนั้นFMUL
ตามค่าคงที่ที่จำเป็น สิ่งนี้น่าจะชนะได้หากเป็นการประกวด [tag: คำแนะนำ: กอล์ฟ] แต่FYL2X
มีเวลาแฝงอยู่ที่ 90-106 สำหรับ Ivy bridge
การค้นหาไบนารี่แบบตายตัว นี่อาจเป็นการแข่งขัน - ฉันจะฝากไว้กับคนอื่นเพื่อนำไปใช้ :)
ทำตารางผลลัพธ์การค้นหาให้สมบูรณ์ นี่ฉันแน่ใจว่าเร็วที่สุดในทางทฤษฎี แต่จะต้องใช้ตารางการค้นหาขนาด 1TB - ยังไม่สามารถใช้งานได้ - อาจใช้เวลาไม่กี่ปีถ้ากฎของมัวร์ยังคงมีอยู่