ในตอนแรกฉันคิดว่าคอมไพเลอร์สามารถสร้างแอสเซมบลีที่เท่ากันสำหรับทั้งสองเวอร์ชันโดยเปิดใช้งานแฟล็กการปรับให้เหมาะสม เมื่อตรวจสอบแล้วฉันรู้สึกประหลาดใจที่เห็นผลลัพธ์:
แหล่ง unoptimized.cpp
หมายเหตุ: รหัสนี้ไม่ได้หมายถึงการเรียกใช้งาน
struct bitmap_t
{
long long width;
} bitmap;
int main(int argc, char** argv)
{
for (unsigned x = 0 ; x < static_cast<unsigned>(bitmap.width) ; ++x)
{
argv[x][0] = '\0';
}
return 0;
}
แหล่ง optimized.cpp
หมายเหตุ: รหัสนี้ไม่ได้หมายถึงการเรียกใช้งาน
struct bitmap_t
{
long long width;
} bitmap;
int main(int argc, char** argv)
{
const unsigned width = static_cast<unsigned>(bitmap.width);
for (unsigned x = 0 ; x < width ; ++x)
{
argv[x][0] = '\0';
}
return 0;
}
การรวบรวม
$ g++ -s -O3 unoptimized.cpp
$ g++ -s -O3 optimized.cpp
แอสเซมบลี (unoptimized.s)
.file "unoptimized.cpp"
.text
.p2align 4,,15
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
.cfi_personality 0x3,__gxx_personality_v0
movl bitmap(%rip), %eax
testl %eax, %eax
je .L2
xorl %eax, %eax
.p2align 4,,10
.p2align 3
.L3:
mov %eax, %edx
addl $1, %eax
movq (%rsi,%rdx,8), %rdx
movb $0, (%rdx)
cmpl bitmap(%rip), %eax
jb .L3
.L2:
xorl %eax, %eax
ret
.cfi_endproc
.LFE0:
.size main, .-main
.globl bitmap
.bss
.align 8
.type bitmap, @object
.size bitmap, 8
bitmap:
.zero 8
.ident "GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-16)"
.section .note.GNU-stack,"",@progbits
แอสเซมบลี (optimized.s)
.file "optimized.cpp"
.text
.p2align 4,,15
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
.cfi_personality 0x3,__gxx_personality_v0
movl bitmap(%rip), %eax
testl %eax, %eax
je .L2
subl $1, %eax
leaq 8(,%rax,8), %rcx
xorl %eax, %eax
.p2align 4,,10
.p2align 3
.L3:
movq (%rsi,%rax), %rdx
addq $8, %rax
cmpq %rcx, %rax
movb $0, (%rdx)
jne .L3
.L2:
xorl %eax, %eax
ret
.cfi_endproc
.LFE0:
.size main, .-main
.globl bitmap
.bss
.align 8
.type bitmap, @object
.size bitmap, 8
bitmap:
.zero 8
.ident "GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-16)"
.section .note.GNU-stack,"",@progbits
diff
$ diff -uN unoptimized.s optimized.s
--- unoptimized.s 2015-11-24 16:11:55.837922223 +0000
+++ optimized.s 2015-11-24 16:12:02.628922941 +0000
@@ -1,4 +1,4 @@
- .file "unoptimized.cpp"
+ .file "optimized.cpp"
.text
.p2align 4,,15
.globl main
@@ -10,16 +10,17 @@
movl bitmap(%rip), %eax
testl %eax, %eax
je .L2
+ subl $1, %eax
+ leaq 8(,%rax,8), %rcx
xorl %eax, %eax
.p2align 4,,10
.p2align 3
.L3:
- mov %eax, %edx
- addl $1, %eax
- movq (%rsi,%rdx,8), %rdx
+ movq (%rsi,%rax), %rdx
+ addq $8, %rax
+ cmpq %rcx, %rax
movb $0, (%rdx)
- cmpl bitmap(%rip), %eax
- jb .L3
+ jne .L3
.L2:
xorl %eax, %eax
ret
แอสเซมบลีที่สร้างขึ้นสำหรับเวอร์ชันที่ปรับให้เหมาะสมจะโหลด ( lea
) width
ค่าคงที่ซึ่งแตกต่างจากเวอร์ชันที่ไม่ได้เพิ่มประสิทธิภาพซึ่งคำนวณค่าwidth
ชดเชยในการทำซ้ำแต่ละครั้ง ( movq
)
เมื่อฉันมีเวลาในที่สุดฉันก็โพสต์เกณฑ์มาตรฐานบางอย่างเกี่ยวกับเรื่องนั้น คำถามที่ดี.
*p
เป็นประเภทเดียวกันwidth
ก็ไม่สำคัญที่จะปรับให้เหมาะสมเนื่องจากp
สามารถชี้width
และแก้ไขภายในลูปได้