for (<init>;<condition>;<increment>)
{
<body>
}
while(<condition>)
{
<body>
}
do
{
<body>
}
while(<condition>)
$ cat loops.c
#include <stdio.h>
fa() {
int i;
for(i=0;i<10;i++)
printf("%d",i);
}
fb() {
int i;
i=0;
while (i<10) {
printf("%d",i);
i++;
}
}
int main() {
fa();
fb();
return 0;
}
(gdb) disass fa
Dump of assembler code for function fa:
0x00401050 <fa+0>: push %ebp
0x00401051 <fa+1>: mov %esp,%ebp
0x00401053 <fa+3>: sub $0x18,%esp
0x00401056 <fa+6>: movl $0x0,0xfffffffc(%ebp)
0x0040105d <fa+13>: cmpl $0x9,0xfffffffc(%ebp)
0x00401061 <fa+17>: jg 0x40107d <fa+45>
0x00401063 <fa+19>: mov 0xfffffffc(%ebp),%eax
0x00401066 <fa+22>: mov %eax,0x4(%esp)
0x0040106a <fa+26>: movl $0x402000,(%esp)
0x00401071 <fa+33>: call 0x401190 <printf>
0x00401076 <fa+38>: lea 0xfffffffc(%ebp),%eax
0x00401079 <fa+41>: incl (%eax)
0x0040107b <fa+43>: jmp 0x40105d <fa+13>
0x0040107d <fa+45>: leave
0x0040107e <fa+46>: ret
End of assembler dump.
(gdb) disass fb
Dump of assembler code for function fb:
0x0040107f <fb+0>: push %ebp
0x00401080 <fb+1>: mov %esp,%ebp
0x00401082 <fb+3>: sub $0x18,%esp
0x00401085 <fb+6>: movl $0x0,0xfffffffc(%ebp)
0x0040108c <fb+13>: cmpl $0x9,0xfffffffc(%ebp)
0x00401090 <fb+17>: jg 0x4010ac <fb+45>
0x00401092 <fb+19>: mov 0xfffffffc(%ebp),%eax
0x00401095 <fb+22>: mov %eax,0x4(%esp)
0x00401099 <fb+26>: movl $0x402000,(%esp)
0x004010a0 <fb+33>: call 0x401190 <printf>
0x004010a5 <fb+38>: lea 0xfffffffc(%ebp),%eax
0x004010a8 <fb+41>: incl (%eax)
0x004010aa <fb+43>: jmp 0x40108c <fb+13>
0x004010ac <fb+45>: leave
0x004010ad <fb+46>: ret
End of assembler dump.
struct justice
{
struct justice *next;
struct justice *prev;
int data;
};
int scandum[1000000];
DO_COMMAND(do_test)
{
int i, j;
struct justice *head = NULL;
struct justice *tail = NULL;
struct justice *temp;
long long scandum_start, scandum_end, justice_start, justice_end;
for (i = 0 ; i < 1000000 ; i++)
{
temp = calloc(1, sizeof(temp));
temp->data = i;
scandum[i] = i;
LINK(temp, head, tail);
}
scandum_start = utime();
for (i = 0 ; i < 1000000 ; i++)
{
j = scandum[i];
}
scandum_end = utime();
justice_start = utime();
for (temp = head ; temp ; temp = temp->next)
{
j = temp->data;
}
justice_end = utime();
scandum_end -= scandum_start;
justice_end -= justice_start;
tintin_printf(ses, "scandum's time: %lld, justice's time: %lld\n", scandum_end, justice_end);
return ses;
}
#10 #test
scandum's time: 17492, justice's time: 58659
scandum's time: 17063, justice's time: 58564
scandum's time: 17326, justice's time: 58812
scandum's time: 16943, justice's time: 59343
scandum's time: 17209, justice's time: 58782
scandum's time: 16662, justice's time: 58803
scandum's time: 17016, justice's time: 61981
scandum's time: 16785, justice's time: 70633
scandum's time: 16854, justice's time: 59469
scandum's time: 17221, justice's time: 58586
#include <stdio.h>
fa() {
int i;
for(i=0;i<10;i++) {
// printf("%d",i);
}
}
fb() {
register int i;
i=0;
while (i<10) {
printf("%d",i);
i++;
}
}
int main() {
fa();
fb();
return 0;
}
$ gcc -O2 -S -c loops.c
$ cat loops.s
.file "loops.c"
.text
.p2align 4,,15
.globl _fa
.def _fa; .scl 2; .type 32; .endef
_fa:
pushl %ebp
movl $9, %eax
movl %esp, %ebp
.p2align 4,,15
L5:
decl %eax
jns L5
popl %ebp
ret
.section .rdata,"dr"
LC0:
.ascii "%d\0"
.text
.p2align 4,,15
.globl _fb
.def _fb; .scl 2; .type 32; .endef
_fb:
pushl %ebp
movl %esp, %ebp
pushl %ebx
subl $20, %esp
xorl %ebx, %ebx
.p2align 4,,15
L12:
movl %ebx, 4(%esp)
incl %ebx
movl $LC0, (%esp)
call _printf
cmpl $9, %ebx
jle L12
addl $20, %esp
popl %ebx
popl %ebp
ret
.def ___main; .scl 2; .type 32; .endef
.p2align 4,,15
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl $16, %eax
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
call __alloca
call ___main
call _fa
call _fb
leave
xorl %eax, %eax
ret
.def _printf; .scl 3; .type 32; .endef
$ gcc -O2 -funroll-all-loops -S -c loops.c
$ cat loops.s
.file "loops.c"
.text
.p2align 4,,15
.globl _fa
.def _fa; .scl 2; .type 32; .endef
_fa:
pushl %ebp
movl %esp, %ebp
popl %ebp
ret
.section .rdata,"dr"
LC0:
.ascii "%d\0"
.text
.p2align 4,,15
.globl _fb
.def _fb; .scl 2; .type 32; .endef
_fb:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
xorl %edx, %edx
movl %edx, 4(%esp)
movl $LC0, (%esp)
call _printf
movl $LC0, (%esp)
movl $1, %eax
movl %eax, 4(%esp)
call _printf
movl $LC0, (%esp)
movl $2, %eax
movl %eax, 4(%esp)
call _printf
movl $LC0, (%esp)
movl $3, %eax
movl %eax, 4(%esp)
call _printf
movl $LC0, (%esp)
movl $4, %eax
movl %eax, 4(%esp)
call _printf
movl $LC0, (%esp)
movl $5, %eax
movl %eax, 4(%esp)
call _printf
movl $LC0, (%esp)
movl $6, %eax
movl %eax, 4(%esp)
call _printf
movl $LC0, (%esp)
movl $7, %ecx
movl %ecx, 4(%esp)
call _printf
movl $LC0, (%esp)
movl $8, %edx
movl %edx, 4(%esp)
call _printf
movl $LC0, (%esp)
movl $9, %eax
movl %eax, 4(%esp)
call _printf
leave
ret
.def ___main; .scl 2; .type 32; .endef
.p2align 4,,15
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl $16, %eax
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
call __alloca
call ___main
call _fa
call _fb
leave
xorl %eax, %eax
ret
.def _printf; .scl 3; .type 32; .endef
So my ultimate question to you, and to all is, What loop is your preferance. Would you sooner write a for(;;) loop then to write a do { }while(condition); loop. And why.
And if you've got a method for optimizing loops, nomatter the kind, how do you go about doing so, and why you've chosen that way. Hell, this is just crazy enough to be helpful.