LINUX.ORG.RU

История изменений

Исправление AIv, (текущая версия) :

Шоу маст гоу он!

Итак, референсный код. Я выкинул все лишнее, область считаем квадратной, проверка только на сумму (можно конечно сравниться с аналитическим решением, но мне лень).

//diffuz2D.cpp
#include <math.h>
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>

const double D = 1.; // коэффициент диффузии
const double h = 1e-4; // шаг по времени
const double A = 1-4*D*h, B = D*h;

struct Cell{ float u, tmp_u; };

int main(int argc, const char** argv){
	if(argc!=3){ printf("usage ./diffuz2D Nspace Ndrops\n"); return 1; }
	int N = atoi(argv[1]), Ndrops = atoi(argv[2]); // размер области и число больших шагов по времени 
	Cell* data = new Cell[N*N];
	for(int iy=0; iy<N; iy++)  // начальные условия
		for(int ix=0; ix<N; ix++) 
			data[ix+iy*N].u = (ix==.5*N && iy==.5*N) ? 1. : 0.;
	double start = omp_get_wtime();
	for(int it=0; it<Ndrops*N; it++){
		for(int iy=1; iy<N-1; iy++)
			for(int ix=1; ix<N-1; ix++){ 
				long offset = ix+iy*N;
				data[offset].tmp_u = A*data[offset].u + 
					B*( data[offset-1].u + data[offset+1].u + data[offset-N].u + data[offset+N].u );
			}
		for(int iy=1; iy<N-1; iy++)
			for(int ix=1; ix<N-1; ix++) data[ix+iy*N].u = data[ix+iy*N].tmp_u;
	}
	double finish = omp_get_wtime(), ch_sum = 0.;
	for(long i=0; i<(long)N*N; i++) ch_sum += data[i].u;	
	printf("%i %i %f %f\n", N, N*Ndrops, finish-start, ch_sum);
	delete []data; 
	return 0;
}
собирать командой
g++ -o diffuz2D -O3 diffuz2D.cpp -lgomp
У меня на стареньком коре 2 дуо 19 тактов на ячейку на шаг. Можно сделать такой же 3D.

Исходная версия AIv, :

Шоу маст гоу он!

Итак, референсный код. Я выкинул все лишнее, область считаем квадратичной, проверка только на сумму (можно конечно сравниться с аналитическим решением, но мне лень).

//diffuz2D.cpp
#include <math.h>
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>

const double D = 1.; // коэффициент диффузии
const double h = 1e-4; // шаг по времени
const double A = 1-4*D*h, B = D*h;

struct Cell{ float u, tmp_u; };

int main(int argc, const char** argv){
	if(argc!=3){ printf("usage ./diffuz2D Nspace Ndrops\n"); return 1; }
	int N = atoi(argv[1]), Ndrops = atoi(argv[2]); // размер области и число больших шагов по времени 
	Cell* data = new Cell[N*N];
	for(int iy=0; iy<N; iy++)  // начальные условия
		for(int ix=0; ix<N; ix++) 
			data[ix+iy*N].u = (ix==.5*N && iy==.5*N) ? 1. : 0.;
	double start = omp_get_wtime();
	for(int it=0; it<Ndrops*N; it++){
		for(int iy=1; iy<N-1; iy++)
			for(int ix=1; ix<N-1; ix++){ 
				long offset = ix+iy*N;
				data[offset].tmp_u = A*data[offset].u + 
					B*( data[offset-1].u + data[offset+1].u + data[offset-N].u + data[offset+N].u );
			}
		for(int iy=1; iy<N-1; iy++)
			for(int ix=1; ix<N-1; ix++) data[ix+iy*N].u = data[ix+iy*N].tmp_u;
	}
	double finish = omp_get_wtime(), ch_sum = 0.;
	for(long i=0; i<(long)N*N; i++) ch_sum += data[i].u;	
	printf("%i %i %f %f\n", N, N*Ndrops, finish-start, ch_sum);
	delete []data; 
	return 0;
}
собирать командой
g++ -o diffuz2D -O3 diffuz2D.cpp -lgomp
У меня на стареньком коре 2 дуо 19 тактов на ячейку на шаг. Можно сделать такой же 3D.