I did some simple speed measurement and can not understand the results. I measured just 1 million additions, then I measured 1 million subtractions and results are way different. It shows that I don't quite understand what is going on 'inside'. I would really appreciate if someone explain why:
my code:
#include "stdio.h" /* i changed brackets into double quotes */
#include "fcntl.h" /* on these include statements just for forum */
#include "sys/time.h" /* as the brackets are treated as html */
#define MAX 1000000
main(int argc, char *argv[])
{
struct timeval t1, t2;
printf("Additions:\n");
gettimeofday(&t1, NULL);
for(i = 0; i < MAX; i++);
gettimeofday(&t2, NULL);
showdiff(t1, t2);
printf("Subtractions:\n");
gettimeofday(&t1, NULL);
for(i = MAX; i < 0; i--);
gettimeofday(&t2, NULL);
showdiff(t1, t2);
}
#define MICROX 1000000.0
showdiff(t1, t2)
struct timeval t1;
struct timeval t2;
{
double secs;
if(t1.tv_usec > t2.tv_usec)
{
secs = ((MICROX + (t2.tv_usec - t1.tv_usec)) / MICROX);
}
else
{
secs = (t2.tv_usec-t1.tv_usec) / MICROX;
}
secs += t2.tv_sec - t1.tv_sec;
printf("Interval: %.6f secs\n", secs);
}
Compiled and run
$ cc -gc measure_time.c && cc -o measure_time measure_time.o
(I specifically added -g to turn off all optimization)
$ measure_time
Additions:
Interval: 0.001876 secs
Subtractions:
Interval: 0.000001 secs
This is SCO OpenServer (3.2 MHz Xeon) system.
On the same hardware under Linux kernel 2.6.9 results are proportionally same.
Why my i-- code takes no time, where i++ does take some time?
Ahem, you might want to add
Ahem, you might want to add a couple of debug statements to check how many times that second loop actually gets executed ;-)
-A
I screwed up badly! Sorry
I screwed up badly! Sorry for not thinking before posting my question. Of cource I need
for(i = MAX; i > 0; i--)
in my do_minus code.
I tried same measurements with multiplication and division of float data, and I see the division is much faster, BUT I don't see any glaring mistakes. Would anyone look at this and point me into right direction?
do_multiplication()
{
int i;
double x = 1.5;
gettimeofday(&t1, NULL);
for(i = 0; i < MAX; i++)
x = x * 1.0001;
gettimeofday(&t2, NULL);
showdiff(t1, t2);
}
do_divisions()
{
int i;
double x = MAX;
gettimeofday(&t1, NULL);
for(i = 0; i < MAX; i++)
x = x / 1.0001;
gettimeofday(&t2, NULL);
showdiff(t1, t2);
}
results show my division roughly twice as fast as mutiplication - there must be a catch, but where?
compile to assembler and
compile to assembler and work out yourself?
gcc -S ...
cc -S ...
I don't know much x86
I don't know much x86 assembler.
I see my problem, in my code variable x looses its fractional part soon and all consequitive arithmetics are not representative - I hope this is actual problem.
I changed my computational statement to:
y = x / some_float_number;
and now results are consistant.
Good that you solved your
Good that you solved your problem.
Its quite educational to take the time to compile simple
code sequences and see what they look like, followed by small
changes to see the before/after effect. You can learn quite
a lot about assembler by seeing live examples like this, and, if
you really care about optimisation, it gears you up for being able
to read full blown assembler guides and instruction timings, etc.
Sometimes you meet an instruction whose name/purpose is not obvious,
and then you can just research on the web or try out other things.
good luck