рд╡рд┐рднрд┐рдиреНрди рд▓реЗрдЦрдХреЛрдВ рдХреЗ рдХрдЪреНрдЪреЗ рдорд╛рд▓ рдореЗрдВ рдореИрдВрдиреЗ рд╕рддрдд рдЪрдХреНрд░ рдХреЗ рд╡рд┐рднрд┐рдиреНрди рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЛ рджреЗрдЦрд╛ред рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдмрд╛рд░ рдореИрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдорд┐рд▓рд╛:
while (true) { ... }
рдФрд░
for (;;) { ... }
рдЪреВрдВрдХрд┐ рд╕рднреА рдиреЗ рдореВрд▓ рдХреЗ рд░реВрдк рдореЗрдВ "рдЕрдкрдиреЗ рд╢рд╛рд╢реНрд╡рдд рдЪрдХреНрд░" рдХрд╛ рдмрдЪрд╛рд╡ рдХрд┐рдпрд╛ рдерд╛, рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдЗрд╕рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рд╕рдмрд╕реЗ рдЗрд╖реНрдЯрддрдо рдХреЛрдб рдХреМрди рд▓рд┐рдЦрддрд╛ рд╣реИред
рдореИрдВрдиреЗ 2 рд╕реНрд░реЛрдд рдХреЛрдб рд▓рд┐рдЦреЗ:
while.c:
#include <stdio.h> int main (int argc, char* argv[]) { while(1){ printf("1\n"); } }
for.c:
#include <stdio.h> int main (int argc, char* argv[]) { for(;;){ printf("1\n"); } }
рдЙрдиреНрд╣реЗрдВ рдПрдХрддреНрд░ рдХрд┐рдпрд╛:
$ gcc -O3 while.c -o while.o3 $ gcc -O2 while.c -o while.o2 $ gcc -O1 while.c -o while.o1 $ gcc -O3 for.c -o for.o3 $ gcc -O2 for.c -o for.o2 $ gcc -O1 for.c -o for.o1
рдФрд░ рдЕрд╕рдВрддреБрд╖реНрдЯред рдХреЛрдбрд╛рдВрддрд░рдХ рд╕реВрдЪрд┐рдпреЛрдВ рдХреЛ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдХреМрди рдмрд╣реБрдд рдЖрд▓рд╕реА рд╣реИ - рдЖрдк рдкреГрд╖реНрда рдХреЛ рдиреАрдЪреЗ рд╕реНрдХреНрд░реЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ:
$ objdump -d ./while.o3 ... 0000000000400430 <main>: 400430: 48 83 ec 08 sub $0x8,%rsp 400434: 0f 1f 40 00 nopl 0x0(%rax) 400438: bf d4 05 40 00 mov $0x4005d4,%edi 40043d: e8 be ff ff ff callq 400400 <puts@plt> 400442: eb f4 jmp 400438 <main+0x8> ... $ objdump -d ./while.o2 ... 0000000000400430 <main>: 400430: 48 83 ec 08 sub $0x8,%rsp 400434: 0f 1f 40 00 nopl 0x0(%rax) 400438: bf d4 05 40 00 mov $0x4005d4,%edi 40043d: e8 be ff ff ff callq 400400 <puts@plt> 400442: eb f4 jmp 400438 <main+0x8> ... $ objdump -d ./while.o1 ... 000000000040051c <main>: 40051c: 48 83 ec 08 sub $0x8,%rsp 400520: bf d4 05 40 00 mov $0x4005d4,%edi 400525: e8 d6 fe ff ff callq 400400 <puts@plt> 40052a: eb f4 jmp 400520 <main+0x4> ... $ objdump -d ./for.o1 ... 000000000040051c <main>: 40051c: 48 83 ec 08 sub $0x8,%rsp 400520: bf d4 05 40 00 mov $0x4005d4,%edi 400525: e8 d6 fe ff ff callq 400400 <puts@plt> 40052a: eb f4 jmp 400520 <main+0x4> ... $ objdump -d ./for.o2 ... 0000000000400430 <main>: 400430: 48 83 ec 08 sub $0x8,%rsp 400434: 0f 1f 40 00 nopl 0x0(%rax) 400438: bf d4 05 40 00 mov $0x4005d4,%edi 40043d: e8 be ff ff ff callq 400400 <puts@plt> 400442: eb f4 jmp 400438 <main+0x8> ... $ objdump -d ./for.o3 0000000000400430 <main>: 400430: 48 83 ec 08 sub $0x8,%rsp 400434: 0f 1f 40 00 nopl 0x0(%rax) 400438: bf d4 05 40 00 mov $0x4005d4,%edi 40043d: e8 be ff ff ff callq 400400 <puts@plt> 400442: eb f4 jmp 400438 <main+0x8>
рд╣рдо рдЙрдВрдЧрд▓рд┐рдпреЛрдВ рдкрд░ рдЬреБрджрд╛ рд╣реЛрддреЗ рд╣реИрдВ
рд╡рд┐рднрд┐рдиреНрди рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝реЗрд╢рди рдиреЗ (рд╕рдЪреНрдЪреЗ) рд▓реВрдк рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ - рд╡рд╣ рд╣рдореЗрд╢рд╛ 3 рдХрдорд╛рдВрдб рдЪрд▓рд╛рддрд╛ рдерд╛: mov, callq рдФрд░ jmpред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЕрдиреБрдХреВрд▓рди рдиреЗ рдЗрд╕рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ - рдпрд╣ рднреА рд╣рдореЗрд╢рд╛ 3 рдХрдорд╛рдВрдбреЛрдВ рд╕реЗ рдерд╛: mov, callq, jmpред рдЦреБрдж рдХреЗ рдмреАрдЪ рдореЗрдВ mov, callq рдФрд░ jmp рдЕрд▓рдЧ рдирд╣реАрдВ рдереЗред рд╕рднреА 6 рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдмрд╛рдЗрдЯреНрд╕ рдореЗрдВ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреА рд▓рдВрдмрд╛рдИ рдЕрдкрд░рд┐рд╡рд░реНрддрд┐рдд рд╣реИред
-O1 рдФрд░ -O2 / -O3 jmp рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдмреАрдЪ рдореБрдЦреНрдп + 4 рдкрд░ рдорд╛рдореВрд▓реА рдЕрдВрддрд░ рд╣реИ рдФрд░ рдореБрдЦреНрдп + 8 рдкрд░ рдирд╣реАрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рджреЗрдЦрддреЗ рд╣реБрдП рдХрд┐ рдпрд╣ рдПрдХ рд╕реНрдереИрддрд┐рдХ рдкрддрд╛ рд╣реИ (asm рдХреЛрдб рд╕реЗ рджреЗрдЦрд╛ рдЧрдпрд╛) рдЗрд╕реЗ рднреА рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛ рд╣реИ рдкреНрд░рджрд░реНрд╢рди ... рд╣рд╛рд▓рд╛рдБрдХрд┐ ... рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдореЗрдореЛрд░реА рдкреЗрдЬ рдЕрд▓рдЧ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдЬрд╣рд╛рдБ рддрдХ рдореБрдЭреЗ x86 (рдФрд░ amd64) рдореЗрдВ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдореЗрдореЛрд░реА рдкреЗрдЬреЛрдВ рдХреЗ рдмреАрдЪ рдЗрд╢рд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдкрддрд╛ рд╣реИ, рдЕрддрд┐рд░рд┐рдХреНрдд рдкреНрд░рдпрд╛рд╕реЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ!
рд╣рдо рд╕реАрдЦрддреЗ рд╣реИрдВ:
400438/4096 = 97.763183594
400520/4096 = 97.783203125
рд▓реЗ рдЧрдПред рдореЗрдореЛрд░реА рдкреЗрдЬ рдПрдХ рд╣реИред рд╣рд╛рдВ, рдпрд╣ рд╡рд░реНрдЪреБрдЕрд▓ рдПрдбреНрд░реЗрд╕ рдСрдлрд╝ рдж рд╡рд░реНрдЪреБрдЕрд▓ рдПрдбреНрд░реЗрд╕ рдСрдлрд╝ рдж рдкреНрд░реЛрд╕реЗрд╕ рдХрд╛ 97 рд╡рд╛рдВ рдкреЗрдЬ рд╣реИред рд▓реЗрдХрд┐рди рд╣рдореЗрдВ рдЗрд╕рдХреА рдЬрд░реВрд░рдд рднреА рд╣реИред
рдкрд░рд┐рдгрд╛рдо
рдЬрдмрдХрд┐ (рд╕рддреНрдп) рдФрд░ (;;) рдПрдХ рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рдФрд░ рдХрд┐рд╕реА рднреА -Ox рдЕрдиреБрдХреВрд▓рди рдХреЗ рд╕рд╛рде рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рд╕рдорд╛рди рд╣реИрдВред рдЗрд╕рд▓рд┐рдП рдпрджрд┐ рдЖрдкрд╕реЗ рдкреВрдЫрд╛ рдЬрд╛рдП рдХрд┐ рдЙрдирдореЗрдВ рд╕реЗ рдХреМрди рд╕рд╛ рддреЗрдЬ рд╣реИ - рдпрд╣ рдХрд╣рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВ рдХрд┐ "рдХреЗ рд▓рд┐рдП (?)" - 8 рдЕрдХреНрд╖рд░ "рдЬрдмрдХрд┐ (рд╕рдЪреНрдЪрд╛)" рд╕реЗ рддреЗрдЬ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП - 12 рд╡рд░реНрдгред
рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЛ рдпрд╣ рд╡рд┐рд╢реНрд╡рд╛рд╕ рдирд╣реАрдВ рдХрд░рддреЗ рдХрд┐ рдмрд┐рдирд╛ -рдУрдПрдХреНрд╕ рдХреЗ рдпрд╣ рд╕рдорд╛рди рд╣реЛрдЧрд╛:
$ gcc while.c -o while.noO $ objdump -d while.noO ... 40052b: bf e4 05 40 00 mov $0x4005e4,%edi 400530: e8 cb fe ff ff callq 400400 <puts@plt> 400535: eb f4 jmp 40052b <main+0xf> ... $ gcc for.c -o for.noO $ objdump -d for.noO ... 40052b: bf e4 05 40 00 mov $0x4005e4,%edi 400530: e8 cb fe ff ff callq 400400 <puts@plt> 400535: eb f4 jmp 40052b <main+0xf> ...
рдкреБрдирд╢реНрдЪ , рдпрд╣ рд╕рдм рд╕рдВрдХрд▓рдХ рдкрд░ рд╕рдЪ рд╣реЛрдЧрд╛ "gcc рд╕рдВрд╕реНрдХрд░рдг 4.7.2 (рдбреЗрдмрд┐рдпрди 4.7.2-5)"