multiple buffer posibility

improvement-multiple_buffers
Oli 3 years ago
parent 4bfd5c1718
commit 7ff79a535a

@ -21,6 +21,7 @@ typedef struct chunk_array {
double* mmap_array; double* mmap_array;
buffer_t* buffer1; buffer_t* buffer1;
buffer_t* buffer2; buffer_t* buffer2;
buffer_t** buffers;
}chunk_array_t; }chunk_array_t;
chunk_array_t* chunk_array_create(char* filename, size_t total_size); chunk_array_t* chunk_array_create(char* filename, size_t total_size);
@ -31,8 +32,6 @@ bool chunk_array_get(chunk_array_t* chunk_array, size_t pos, double *value_ptr);
bool chunk_array_save(chunk_array_t* chunk_array, size_t pos, double valor); bool chunk_array_save(chunk_array_t* chunk_array, size_t pos, double valor);
void chunk_array_flush(chunk_array_t* chunk_array);
size_t chunk_array_size(chunk_array_t* chunk_array); size_t chunk_array_size(chunk_array_t* chunk_array);
#endif #endif

@ -3,7 +3,8 @@
#include "stdlib.h" #include "stdlib.h"
#include <sys/mman.h> #include <sys/mman.h>
#define MAX_CHUNK_SIZE 2048*2048 #define MAX_CHUNK_SIZE 2048
#define N_BUFFERS 3
int min(int value1, int value2) { int min(int value1, int value2) {
if (value1 < value2) return value1; if (value1 < value2) return value1;
@ -28,23 +29,17 @@ bool inside_buffer(chunk_array_t* chunk_array,int init_pos, size_t pos) {
} }
void chunk_array_free(chunk_array_t* chunk_array) { void chunk_array_free(chunk_array_t* chunk_array) {
//fclose(chunk_array->fp); if (chunk_array->mmap_array) munmap(chunk_array->mmap_array, chunk_array->total_size * sizeof(double));
munmap(chunk_array->mmap_array, chunk_array->total_size * sizeof(double)); for (int i = 0; i < N_BUFFERS; i++) {
buffer_free(chunk_array->buffer1); buffer_free(chunk_array->buffers[i]);
buffer_free(chunk_array->buffer2); }
free(chunk_array->buffers);
free(chunk_array); free(chunk_array);
} }
void chunk_array_flush(chunk_array_t* chunk_array) {
buffer_flush(chunk_array, chunk_array->buffer1);
buffer_flush(chunk_array, chunk_array->buffer2);
}
void buffer_flush(chunk_array_t* chunk_array, buffer_t* buffer) { void buffer_flush(chunk_array_t* chunk_array, buffer_t* buffer) {
if (buffer->dirty) { if (buffer->dirty) {
int mod = get_mod(chunk_array, buffer->init_pos); int mod = get_mod(chunk_array, buffer->init_pos);
//fseek(chunk_array->fp, buffer->init_pos * sizeof(double), SEEK_SET);
//fwrite(buffer->data, sizeof(double), mod, chunk_array->fp);
memcpy(&chunk_array->mmap_array[buffer->init_pos], buffer->data, mod * sizeof(double)); memcpy(&chunk_array->mmap_array[buffer->init_pos], buffer->data, mod * sizeof(double));
buffer->dirty = false; buffer->dirty = false;
@ -59,8 +54,6 @@ void buffer_update(chunk_array_t* chunk_array, buffer_t* buffer, size_t pos) {
buffer->init_pos = new_init * chunk_array->chunk_size; buffer->init_pos = new_init * chunk_array->chunk_size;
int mod = get_mod(chunk_array, buffer->init_pos); int mod = get_mod(chunk_array, buffer->init_pos);
//fseek(chunk_array->fp, buffer->init_pos * sizeof(double), SEEK_SET);
//fread(buffer->data, sizeof(double), chunk_array->chunk_size, chunk_array->fp);
memcpy(buffer->data, &chunk_array->mmap_array[buffer->init_pos], mod * sizeof(double)); memcpy(buffer->data, &chunk_array->mmap_array[buffer->init_pos], mod * sizeof(double));
} }
@ -94,65 +87,75 @@ chunk_array_t* chunk_array_create(char* filename, size_t total_size) {
return NULL; return NULL;
} }
chunk_array->chunk_size = min(MAX_CHUNK_SIZE, total_size);
if (chunk_array->chunk_size*N_BUFFERS < total_size) {
chunk_array->mmap_array = mmap ( NULL, total_size*sizeof(double), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0 ); chunk_array->mmap_array = mmap ( NULL, total_size*sizeof(double), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0 );
if (chunk_array->mmap_array == NULL) { if (chunk_array->mmap_array == NULL) {
return NULL; return NULL;
} }
chunk_array->chunk_size = min(MAX_CHUNK_SIZE, total_size); }
chunk_array->buffer1 = buffer_create(chunk_array->chunk_size); chunk_array->buffers = malloc(sizeof(buffer_t) * N_BUFFERS);
if (chunk_array->buffer1 == NULL) { chunk_array->buffers[0] = buffer_create(chunk_array->chunk_size);
fclose(chunk_array->fp);
free(chunk_array);
return NULL;
}
chunk_array->buffer2 = buffer_create(chunk_array->chunk_size); chunk_array->buffers[0]->init_pos = 0;
if (chunk_array->buffer2 == NULL) { for (int i = 1; i<N_BUFFERS; i++) {
//fclose(chunk_array->fp); if (total_size > i*chunk_array->chunk_size) {
buffer_free(chunk_array->buffer1); chunk_array->buffers[i] = buffer_create(chunk_array->chunk_size);
free(chunk_array); chunk_array->buffers[i]->init_pos = chunk_array->chunk_size;
return NULL; } else {
break;
} }
memcpy(chunk_array->buffer1->data, chunk_array->mmap_array, chunk_array->chunk_size * sizeof(double));
chunk_array->buffer1->init_pos = 0;
if (total_size > chunk_array->chunk_size) {
int mod = get_mod(chunk_array, chunk_array->buffer1->init_pos + chunk_array->chunk_size);
memcpy(chunk_array->buffer2->data, &chunk_array->mmap_array[chunk_array->chunk_size], mod * sizeof(double));
chunk_array->buffer2->init_pos = chunk_array->chunk_size;
} }
chunk_array->filename = filename; chunk_array->filename = filename;
chunk_array->total_size = total_size; chunk_array->total_size = total_size;
return chunk_array; return chunk_array;
} }
buffer_t* chunk_array_update(chunk_array_t* chunk_array, size_t pos) { buffer_t* chunk_array_update(chunk_array_t* chunk_array, size_t pos) {
int distance_to_1 = abs(chunk_array->buffer1->init_pos - pos);
int distance_to_2 = abs(chunk_array->buffer2->init_pos - pos);
if (distance_to_1 < distance_to_2) { buffer_t* buffer = chunk_array->buffers[0];
buffer_update(chunk_array, chunk_array->buffer1, pos); int distance = abs(buffer->init_pos - pos);
return chunk_array->buffer1;
printf("[CHUNK UPDATE][%s] pos: %d \n",chunk_array->filename, pos);
for(int i=1; i<N_BUFFERS; i++) {
int new_distance = abs(chunk_array->buffers[i]->init_pos - pos);
if (new_distance < distance) {
distance = new_distance;
buffer = chunk_array->buffers[i];
} }
buffer_update(chunk_array, chunk_array->buffer2, pos); }
return chunk_array->buffer2;
buffer_update(chunk_array, buffer, pos);
return buffer;
} }
bool chunk_array_get(chunk_array_t* chunk_array, size_t pos, double *valor) { bool chunk_array_get(chunk_array_t* chunk_array, size_t pos, double *valor) {
buffer_t* buffer; // full memory
if (inside_buffer(chunk_array, chunk_array->buffer1->init_pos, pos)) { if (chunk_array->total_size <= chunk_array->chunk_size) {
buffer = chunk_array->buffer1; *valor=chunk_array->buffers[0]->data[pos];
return true;
}
// mmap
buffer_t* buffer = NULL;
for (int i = 0; i<N_BUFFERS; i++) {
if (inside_buffer(chunk_array, chunk_array->buffers[i]->init_pos, pos)) {
buffer = chunk_array->buffers[i];
} }
else if (inside_buffer(chunk_array, chunk_array->buffer2->init_pos, pos)) {
buffer = chunk_array->buffer2;
} }
else {
// need to update one buffer if (!buffer) {
buffer = chunk_array_update(chunk_array, pos); buffer = chunk_array_update(chunk_array, pos);
} }
@ -163,15 +166,23 @@ bool chunk_array_get(chunk_array_t* chunk_array, size_t pos, double *valor) {
bool chunk_array_save(chunk_array_t* chunk_array, size_t pos, double valor) { bool chunk_array_save(chunk_array_t* chunk_array, size_t pos, double valor) {
buffer_t* buffer; // full memory
if (inside_buffer(chunk_array, chunk_array->buffer1->init_pos, pos)) { if (chunk_array->total_size <= chunk_array->chunk_size) {
buffer = chunk_array->buffer1; chunk_array->buffers[0]->data[pos]=valor;
chunk_array->buffers[0]->dirty = true;
return true;
} }
else if (inside_buffer(chunk_array, chunk_array->buffer2->init_pos, pos)) {
buffer = chunk_array->buffer2; // mmap
buffer_t* buffer = NULL;
for (int i = 0; i<N_BUFFERS; i++) {
if (inside_buffer(chunk_array, chunk_array->buffers[i]->init_pos, pos)) {
buffer = chunk_array->buffers[i];
} }
else { }
// need to update one buffer
if (!buffer) {
buffer = chunk_array_update(chunk_array, pos); buffer = chunk_array_update(chunk_array, pos);
} }
int real_pos = pos%get_mod(chunk_array, buffer->init_pos); int real_pos = pos%get_mod(chunk_array, buffer->init_pos);

@ -69,42 +69,25 @@ void FFTMA2(struct vario_mod variogram, struct grid_mod grid, int n[3], struct r
printf("termine covariance\n"); printf("termine covariance\n");
chunk_array_flush(covar);
/*power spectrum*/ /*power spectrum*/
fourt(covar, ireal, n, NDIM, 1, 0, workr, worki); fourt(covar, ireal, n, NDIM, 1, 0, workr, worki);
chunk_array_flush(covar);
chunk_array_flush(ireal);
/*organization of the input Gaussian white noise*/ /*organization of the input Gaussian white noise*/
solver = 0; solver = 0;
prebuild_gwn(grid, n, realin, realization, solver, seed); prebuild_gwn(grid, n, realin, realization, solver, seed);
chunk_array_flush(realization);
/*forward fourier transform of the GWN*/ /*forward fourier transform of the GWN*/
fourt(realization, ireal, n, NDIM, 1, 0, workr, worki); fourt(realization, ireal, n, NDIM, 1, 0, workr, worki);
chunk_array_flush(realization);
chunk_array_flush(ireal);
/* build realization in spectral domain */ /* build realization in spectral domain */
build_real(n, NTOT, covar, realization, ireal); build_real(n, NTOT, covar, realization, ireal);
chunk_array_flush(realization);
chunk_array_free(covar); chunk_array_free(covar);
remove("covar.txt");
/*backward fourier transform*/ /*backward fourier transform*/
fourt(realization, ireal, n, NDIM, 0, 1, workr, worki); fourt(realization, ireal, n, NDIM, 0, 1, workr, worki);
chunk_array_flush(realization);
chunk_array_flush(ireal);
chunk_array_free(ireal); chunk_array_free(ireal);
remove("ireal.txt");
free(workr); free(workr);
free(worki); free(worki);

@ -3,7 +3,7 @@
#include <time.h> #include <time.h>
#include "chunk_array.h" #include "chunk_array.h"
/*fast fourier transform */ /* fast fourier transform */
/* THE COOLEY-TUKEY FAST FOURIER TRANSFORM */ /* THE COOLEY-TUKEY FAST FOURIER TRANSFORM */
/* EVALUATES COMPLEX FOURIER SERIES FOR COMPLEX OR REAL FUNCTIONS. */ /* EVALUATES COMPLEX FOURIER SERIES FOR COMPLEX OR REAL FUNCTIONS. */
/* THAT IS, IT COMPUTES */ /* THAT IS, IT COMPUTES */
@ -333,8 +333,13 @@ void fourt(chunk_array_t* datar, chunk_array_t* datai, int nn[3], int ndim, int
chunk_array_save(datar, i, valuerj - tempr); chunk_array_save(datar, i, valuerj - tempr);
chunk_array_save(datai, i, valueij - tempi); chunk_array_save(datai, i, valueij - tempi);
chunk_array_get(datar, j, &valuerj); //chunk_array_get(datar, j, &valuerj);
chunk_array_get(datai, j, &valueij); //chunk_array_get(datai, j, &valueij);
printf("start\n");
printf("[GET] %d\n", j);
printf("[SAVE] %d\n", i);
printf("[SAVE] %d\n", j);
printf("end\n");
chunk_array_save(datar, j, valuerj + tempr); chunk_array_save(datar, j, valuerj + tempr);
chunk_array_save(datai, j, valueij + tempi); chunk_array_save(datai, j, valueij + tempi);

Loading…
Cancel
Save