-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Also benchmarks should not rely on convergence, rather a fixed number of iterations is more appropriate. The problem of inconsistent iterations between the C and Fortran versions was also fixed because of an indexing error when calculating the cell coordinates (C is 0-based, F is 1-based). So they now run the same number of iterations, regardless of M. Moved timings about to make them more comparable. Ensured that all examples now use allocate/malloc which is much more realistic. Even though it does not have the same performance it is much more appropriate for benchmark cases. Lastly, made calls more similar, C and F both call a function for the iteration step.
- Loading branch information
Showing
4 changed files
with
168 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <math.h> | ||
#include <time.h> | ||
#define M 1000 | ||
#define N_ITER 10000 | ||
|
||
#define IDX(i,j) (i)*M+j | ||
|
||
|
||
double rho(const double x, const double y) { | ||
const double s1 = 0.6; | ||
const double e1 = 0.8; | ||
const double s2 = 0.2; | ||
const double e2 = 0.4; | ||
|
||
if (s1 < x && x < e1 && s1 < y && y < e1) { | ||
return 1.0; | ||
} else if ( s2 < x && x < e2 && s2 < y && y < e2 ) { | ||
return -1.0; | ||
} else { | ||
return 0.0; | ||
} | ||
} | ||
|
||
double iterate(double *restrict phi, double *restrict phinew, double *restrict rhoa) { | ||
double delta = 0, err; | ||
for (int i=1; i < M-1; i++) { | ||
for (int j=1; j < M-1; j++) { | ||
phinew[IDX(i,j)] = (phi[IDX(i+1,j)] + phi[IDX(i-1,j)] + phi[IDX(i,j+1)] + phi[IDX(i,j-1)] + rhoa[IDX(i,j)])*0.25; | ||
err = fabs(phinew[IDX(i,j)] - phi[IDX(i,j)]); | ||
if ( err > delta ) delta = err; | ||
} | ||
} | ||
return delta; | ||
} | ||
|
||
void init_rho(double *restrict rhoa, const double epsilon, const double a) { | ||
const double a2 = a * a / epsilon; | ||
for (int i=1; i<M-1; i++) { | ||
for (int j=1; j<M-1; j++) { | ||
rhoa[IDX(i,j)] = rho(i*a,j*a) * a2; | ||
} | ||
} | ||
} | ||
|
||
|
||
void run(const double toler, const double a) | ||
{ | ||
double epsilon0 = 8.85e-12; | ||
|
||
double *phi; | ||
double *phip; | ||
double *rhoa; | ||
double *tmp; | ||
|
||
// A real world program will definitely use malloc | ||
phi = malloc(M*M*sizeof(double)); | ||
phip = malloc(M*M*sizeof(double)); | ||
rhoa = malloc(M*M*sizeof(double)); | ||
|
||
// Only need to initialize one of them! | ||
for (int i = 0 ; i < M*M ; i++ ) | ||
phi[i] = 0.; | ||
for (int i = 0 ; i < M*M ; i++ ) | ||
phip[i] = 0.; | ||
|
||
// In C one tries to avoid using pow because | ||
// it assumes floating point powers (integers are faster) | ||
// So better do it directly | ||
init_rho(rhoa, epsilon0, a); | ||
|
||
int iter = 0; | ||
double delta; | ||
while ( iter < N_ITER ) { | ||
iter += 1; | ||
|
||
delta = iterate(phi, phip, rhoa); | ||
|
||
// swap pointers (no copies) | ||
tmp = phi; | ||
phi = phip; | ||
phip = tmp; | ||
} | ||
|
||
free(phi); | ||
free(phip); | ||
free(rhoa); | ||
|
||
printf("delta = %20.10f\n",delta); | ||
printf("Iterations = %d\n", iter); | ||
} | ||
|
||
int main(int argc, char *argv[]) | ||
{ | ||
const double target = 1e-1; | ||
const double a = 0.01; | ||
|
||
clock_t start = clock(); | ||
printf("c version [1d]\n"); | ||
run(target, a); | ||
clock_t end = clock(); | ||
double total = ((double)(end - start)) / CLOCKS_PER_SEC; | ||
printf("Time = %20.10f\n",total); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters