U
user923005
Eric Sosman a écrit :
Kaz said:Ben Pfaff wrote:
Kelsey Bjarnason wrote:
[...]
Frankly, I'd be surprised if there were any discernible difference
other than possibly on an implementation designed to be
pathological.
In my one-off test, the second method ran 2.5 times faster than
the first. I guess that makes gcc and Opteron "pathological."
Is this on Linux with glibc?Alas, no: Windows Vaster. (My excuse: I'm working with another
company's product, one that requires a Windows-based management
station even when running on a different platform entirely. So a
Windows desktop is pretty much forced upon me.) The C implementation
is the gcc-based DJGPP environment, originally developed for MS-DOS.
I just compiled and profiled it as well, on gcc 4.3.3 on GNU/Linux
Ubuntu, on a regular intel machine.
Method 2 won :
% cumulative self self total
time seconds seconds calls ms/call ms/call name
62.50 0.05 0.05 1 50.00 50.00 method1
37.50 0.08 0.03 1 30.00 30.00 method2
BUT
This first benchmark was a bit simplistic.
So I made a real one, where method1 and method2 are successively called
50 times, and then their calls are interlaced 50 times.
Here is the gprof result (initarrays is just what its name says) :
% cumulative self self total
time seconds seconds calls ms/call ms/call name
51.46 2.99 2.99 100 29.90 29.90 method2
47.50 5.75 2.76 100 27.60 27.60 method1
1.03 5.81 0.06 1 60.00 60.00 initarrays
So we can say that the difference becomes negligible in the real world.
If you're interested, here is my benchmark, full of bugs and
inaccuracies, of course, and with no doubt someone will point out that
this is *not* real world... But, was the original problem real world ?
==========================
#include <malloc.h>
#include <stdio.h>
#include <time.h>
#define N 1024*1024
void initarrays(double *a, double *b, double *c)
{
long int i;
for(i=0; i<N; i++) {
a = 2;
b = 2;
c = 2;
}
}
void method1(double *a, double *b, double *c)
{
long int i;
for(i=0; i<N; i++) {
a *= 1;
b *= 2;
c *= 3;
}
}
void method2(double *a, double *b, double *c)
{
long int i;
for(i=0; i<N; i++) {
a *= 1;
}
for(i=0; i<N; i++) {
b *= 2;
}
for(i=0; i<N; i++) {
c *= 3;
}
}
int main(int argc, char *argv[])
{
time_t start, end;
int i;
double *a = malloc(N * sizeof *a);
double *b = malloc(N * sizeof *b);
double *c = malloc(N * sizeof *c);
initarrays(a, b, c);
printf("Running method 1 50 times...\n");
start = time(NULL);
for(i=0; i<50; i++) {
method1(a, b, c);
}
end = time(NULL);
printf("%ld seconds\n", (unsigned long int)(end - start));
printf("\n");
printf("Running method 2 50 times...\n");
start = time(NULL);
for(i=0; i<50; i++) {
method2(a, b, c);
}
end = time(NULL);
printf("%ld seconds\n", (unsigned long int)(end - start));
printf("\n");
printf("Interlacing method 1 & 2 50 times...\n");
start = time(NULL);
for(i=0; i<50; i++) {
method1(a, b, c);
method2(a, b, c);
}
end = time(NULL);
printf("%ld seconds\n", (unsigned long int)(end - start));
free(a);
free(b);
free(c);
return 0;}
==========================
Here is my adaptation and the default values that I got:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
static size_t N = 1024 * 1024;
static unsigned Iterations = 500;
void initarrays(double *a, double *b, double *c)
{
long int i;
for (i = 0; i < N; i++) {
a = 2;
b = 2;
c = 2;
}
}
void method1(double *a, double *b, double *c)
{
long int i;
for (i = 0; i < N; i++) {
a *= 1;
b *= 2;
c *= 3;
}
}
void method2(double *a, double *b, double *c)
{
long int i;
for (i = 0; i < N; i++) {
a *= 1;
}
for (i = 0; i < N; i++) {
b *= 2;
}
for (i = 0; i < N; i++) {
c *= 3;
}
}
int main(int argc, char *argv[])
{
time_t start,
end;
int i;
double *a;
double *b;
double *c;
size_t v = 0;
if (argc > 1)
v = atof(argv[1]);
if (v > 0)
N = v;
a = malloc(N * sizeof *a);
b = malloc(N * sizeof *b);
c = malloc(N * sizeof *c);
initarrays(a, b, c);
printf("Running method 1 %u times...\n", Iterations);
start = time(NULL);
for (i = 0; i < Iterations; i++) {
method1(a, b, c);
}
end = time(NULL);
printf("%ld seconds\n", (unsigned long int) (end - start));
printf("\n");
printf("Running method 2 %u times...\n", Iterations);
start = time(NULL);
for (i = 0; i < Iterations; i++) {
method2(a, b, c);
}
end = time(NULL);
printf("%ld seconds\n", (unsigned long int) (end - start));
printf("\n");
printf("Interlacing method 1 & 2 %u times...\n", Iterations);
start = time(NULL);
for (i = 0; i < Iterations; i++) {
method1(a, b, c);
method2(a, b, c);
}
end = time(NULL);
printf("%ld seconds\n", (unsigned long int) (end - start));
free(a);
free(b);
free(c);
return 0;
}
/*
Running method 1 500 times...
3 seconds
Running method 2 500 times...
4 seconds
Interlacing method 1 & 2 500 times...
8 seconds
*/