summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2002-06-05 15:19:07 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2002-06-05 15:19:07 (GMT)
commit1eb15039114f4bcda7269cc406111138ceba1f0f (patch)
treefe953b93bf77b54218ceacbac8083886a3d7f5b8
parent1500b00b079e8f50b4836e3156d76ce5a7f178eb (diff)
downloadhdf5-1eb15039114f4bcda7269cc406111138ceba1f0f.zip
hdf5-1eb15039114f4bcda7269cc406111138ceba1f0f.tar.gz
hdf5-1eb15039114f4bcda7269cc406111138ceba1f0f.tar.bz2
[svn-r5535] Purpose:
New feature. Description: Added a "small data" block allocation mechanism to the library, similar to the mechanism used for allocating metadata currently. See the RFC for more details: http://hdf.ncsa.uiuc.edu/RFC/SmallData/SmallData.html This reduces the number of I/O operations which hit the disk for my test program from 19 to 15 (i.e. from 393 to 15, overall). Platforms tested: Solaris 2.7 (arabica) w/FORTRAN and FreeBSD 4.5 (sleipnir) w/C++
-rw-r--r--release_docs/RELEASE.txt2
-rw-r--r--src/H5F.c2
-rw-r--r--src/H5FD.c179
-rw-r--r--src/H5FDfamily.c1
-rw-r--r--src/H5FDgass.c1
-rw-r--r--src/H5FDlog.c1
-rw-r--r--src/H5FDmpio.c1
-rw-r--r--src/H5FDmulti.c1
-rw-r--r--src/H5FDpublic.h11
-rw-r--r--src/H5FDsec2.c1
-rw-r--r--src/H5FDsrb.c1
-rw-r--r--src/H5FDstdio.c1
-rw-r--r--src/H5FDstream.c1
-rw-r--r--src/H5Fprivate.h1
-rw-r--r--src/H5P.c4
15 files changed, 154 insertions, 54 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index 7a8a71b..8f4fd7e 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -42,6 +42,8 @@ New Features
=========
o General
---------
+ * Added internal "small data" aggregation, which can reduce the number of
+ actual I/O calls made, improving performance. QAK - 2002/06/05
* Improved internal metadata aggregation, which can reduce the number of
actual I/O calls made, improving performance. Additionally, this can
reduce the size of files produced. QAK - 2002/06/04
diff --git a/src/H5F.c b/src/H5F.c
index b373e45..cc59183 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -232,6 +232,7 @@ H5F_init_interface(void)
H5F_access_dflt.alignment = 1; /*no alignment*/
H5F_access_dflt.gc_ref = 0; /*don't garbage-collect references*/
H5F_access_dflt.meta_block_size = 2048; /* set metadata block allocations to 2KB */
+ H5F_access_dflt.sdata_block_size = 2048; /* set "small data" block allocations to 2KB */
H5F_access_dflt.sieve_buf_size = 64*1024; /* set sieve buffer allocation to 64KB */
H5F_access_dflt.driver_id = H5FD_SEC2; /*default driver*/
H5F_access_dflt.driver_info = NULL; /*driver file access properties*/
@@ -491,6 +492,7 @@ H5Fget_access_plist(hid_t file_id)
_fapl.alignment = f->shared->alignment;
_fapl.gc_ref = f->shared->gc_ref;
_fapl.meta_block_size = f->shared->lf->def_meta_block_size;
+ _fapl.sdata_block_size = f->shared->lf->def_sdata_block_size;
_fapl.sieve_buf_size = f->shared->sieve_buf_size;
_fapl.driver_id = f->shared->lf->driver_id;
_fapl.driver_info = NULL; /*just for now */
diff --git a/src/H5FD.c b/src/H5FD.c
index 638c756..522e35b 100644
--- a/src/H5FD.c
+++ b/src/H5FD.c
@@ -812,6 +812,7 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
file->maxaddr = maxaddr;
HDmemset(file->fl, 0, sizeof(file->fl));
file->def_meta_block_size = fapl->meta_block_size;
+ file->def_sdata_block_size = fapl->sdata_block_size;
file->accum_loc = HADDR_UNDEF;
file->threshold = fapl->threshold;
file->alignment = fapl->alignment;
@@ -1413,72 +1414,144 @@ H5FD_alloc(H5FD_t *file, H5FD_mem_t type, hsize_t size)
}
#endif
- /*
- * If the metadata aggregation feature is enabled for this VFL driver,
- * allocate "generic" metadata space and sub-allocate out of that, if
- * possible. Otherwise just allocate through H5FD_real_alloc()
- */
- /* Allocate all types of metadata out of the metadata block */
- if((file->feature_flags&H5FD_FEAT_AGGREGATE_METADATA) && type!=H5FD_MEM_DRAW) {
- /* Check if the space requested is larger than the space left in the block */
- if(size>file->cur_meta_block_size) {
- haddr_t new_meta; /* Address for new metadata */
-
- /* Check if the block asked for is too large for a metadata block */
- if(size>=file->def_meta_block_size) {
- /* Allocate more room for this new block the regular way */
- new_meta=H5FD_real_alloc(file,type,size);
-
- /* Check if the new metadata is at the end of the current metadata block */
- if(file->eoma+file->cur_meta_block_size==new_meta) {
- /* Treat the allocation request as if the current metadata block
- * grew by the amount allocated and just update the eoma
- * address. Don't bother updating the cur_meta_block_size
- * since it will just grow and shrink by the same amount.
- */
- ret_value=file->eoma;
- file->eoma+=size;
+ /* Handle metadata differently from "raw" data */
+ if(type!=H5FD_MEM_DRAW) {
+ /*
+ * If the metadata aggregation feature is enabled for this VFL driver,
+ * allocate "generic" metadata space and sub-allocate out of that, if
+ * possible. Otherwise just allocate through H5FD_real_alloc()
+ */
+ /* Allocate all types of metadata out of the metadata block */
+ if(file->feature_flags&H5FD_FEAT_AGGREGATE_METADATA) {
+ /* Check if the space requested is larger than the space left in the block */
+ if(size>file->cur_meta_block_size) {
+ haddr_t new_meta; /* Address for new metadata */
+
+ /* Check if the block asked for is too large for a metadata block */
+ if(size>=file->def_meta_block_size) {
+ /* Allocate more room for this new block the regular way */
+ new_meta=H5FD_real_alloc(file,type,size);
+
+ /* Check if the new metadata is at the end of the current metadata block */
+ if(file->eoma+file->cur_meta_block_size==new_meta) {
+ /* Treat the allocation request as if the current metadata block
+ * grew by the amount allocated and just update the eoma
+ * address. Don't bother updating the cur_meta_block_size
+ * since it will just grow and shrink by the same amount.
+ */
+ ret_value=file->eoma;
+ file->eoma+=size;
+ } /* end if */
+ else {
+ /* Use the new metadata block for the space allocated */
+ ret_value=new_meta;
+ } /* end else */
} /* end if */
else {
- /* Use the new metadata block for the space allocated */
- ret_value=new_meta;
- } /* end else */
- } /* end if */
- else {
- /* Allocate another metadata block */
- new_meta=H5FD_real_alloc(file,H5FD_MEM_DEFAULT,file->def_meta_block_size);
+ /* Allocate another metadata block */
+ new_meta=H5FD_real_alloc(file,H5FD_MEM_DEFAULT,file->def_meta_block_size);
- /* Check if the new metadata is at the end of the current metadata block */
- if(file->eoma+file->cur_meta_block_size==new_meta) {
- file->cur_meta_block_size+=file->def_meta_block_size;
- } /* end if */
- else {
- /*
- * Instead of just dropping the remainder of the block on the
- * floor and leaving the space in the file unused, we should
- * return this small piece of unused space to the free list
- * management. - QAK
- */
- file->eoma=new_meta;
- file->cur_meta_block_size=file->def_meta_block_size;
- } /* end else */
+ /* Check if the new metadata is at the end of the current metadata block */
+ if(file->eoma+file->cur_meta_block_size==new_meta) {
+ file->cur_meta_block_size+=file->def_meta_block_size;
+ } /* end if */
+ else {
+ /*
+ * Instead of just dropping the remainder of the block on the
+ * floor and leaving the space in the file unused, we should
+ * return this small piece of unused space to the free list
+ * management. - QAK
+ */
+ file->eoma=new_meta;
+ file->cur_meta_block_size=file->def_meta_block_size;
+ } /* end else */
+ /* Allocate space out of the metadata block */
+ ret_value=file->eoma;
+ file->cur_meta_block_size-=size;
+ file->eoma+=size;
+ } /* end else */
+ } /* end if */
+ else {
/* Allocate space out of the metadata block */
ret_value=file->eoma;
file->cur_meta_block_size-=size;
file->eoma+=size;
} /* end else */
} /* end if */
- else {
- /* Allocate space out of the metadata block */
- ret_value=file->eoma;
- file->cur_meta_block_size-=size;
- file->eoma+=size;
+ else { /* Allocate data the regular way */
+ ret_value=H5FD_real_alloc(file,type,size);
} /* end else */
} /* end if */
- else { /* Allocate data the regular way */
- ret_value=H5FD_real_alloc(file,type,size);
+ else { /* Allocate "raw" data */
+ /*
+ * If the "small data" aggregation feature is enabled for this VFL driver,
+ * allocate "small data" space and sub-allocate out of that, if
+ * possible. Otherwise just allocate through H5FD_real_alloc()
+ */
+ if(file->feature_flags&H5FD_FEAT_AGGREGATE_SMALLDATA) {
+ /* Check if the space requested is larger than the space left in the block */
+ if(size>file->cur_sdata_block_size) {
+ haddr_t new_data; /* Address for new raw data block */
+
+ /* Check if the block asked for is too large for the "small data" block */
+ if(size>=file->def_sdata_block_size) {
+ /* Allocate more room for this new block the regular way */
+ new_data=H5FD_real_alloc(file,type,size);
+
+ /* Check if the new raw data is at the end of the current "small data" block */
+ if(file->eosda+file->cur_sdata_block_size==new_data) {
+ /* Treat the allocation request as if the current "small data"
+ * block grew by the amount allocated and just update the
+ * eosda address. Don't bother updating the
+ * cur_sdata_block_size since it will just grow and shrink by
+ * the same amount.
+ */
+ ret_value=file->eosda;
+ file->eosda+=size;
+ } /* end if */
+ else {
+ /* Use the new "small data" block for the space allocated */
+ ret_value=new_data;
+ } /* end else */
+ } /* end if */
+ else {
+ /* Allocate another "small data" block */
+ new_data=H5FD_real_alloc(file,type,file->def_sdata_block_size);
+
+ /* Check if the new raw data is at the end of the current "small data" block */
+ if(file->eosda+file->cur_sdata_block_size==new_data) {
+ file->cur_sdata_block_size+=file->def_sdata_block_size;
+ } /* end if */
+ else {
+ /*
+ * Instead of just dropping the remainder of the block on the
+ * floor and leaving the space in the file unused, we should
+ * return this small piece of unused space to the free list
+ * management. - QAK
+ */
+ file->eosda=new_data;
+ file->cur_sdata_block_size=file->def_sdata_block_size;
+ } /* end else */
+
+
+ /* Allocate space out of the "small data" block */
+ ret_value=file->eosda;
+ file->cur_sdata_block_size-=size;
+ file->eosda+=size;
+ } /* end else */
+ } /* end if */
+ else {
+ /* Allocate space out of the "small data" block */
+ ret_value=file->eosda;
+ file->cur_sdata_block_size-=size;
+ file->eosda+=size;
+ } /* end else */
+ } /* end if */
+ else { /* Allocate data the regular way */
+ ret_value=H5FD_real_alloc(file,type,size);
+ } /* end else */
} /* end else */
done:
diff --git a/src/H5FDfamily.c b/src/H5FDfamily.c
index 12a102c..320e916 100644
--- a/src/H5FDfamily.c
+++ b/src/H5FDfamily.c
@@ -639,6 +639,7 @@ H5FD_family_query(const H5FD_t UNUSED *_f, unsigned long *flags /* out */)
*flags|=H5FD_FEAT_AGGREGATE_METADATA; /* OK to aggregate metadata allocations */
*flags|=H5FD_FEAT_ACCUMULATE_METADATA; /* OK to accumulate metadata for faster writes */
*flags|=H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */
+ *flags|=H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
}
FUNC_LEAVE(ret_value);
diff --git a/src/H5FDgass.c b/src/H5FDgass.c
index 26d40c0..41ef7d7 100644
--- a/src/H5FDgass.c
+++ b/src/H5FDgass.c
@@ -463,6 +463,7 @@ H5FD_gass_query(const UNUSED H5FD_t *_f, unsigned long *flags /* out */)
if(flags) {
*flags = 0;
*flags|=H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */
+ *flags|=H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
}
FUNC_LEAVE(ret_value);
diff --git a/src/H5FDlog.c b/src/H5FDlog.c
index 67d3a0b..0fdfe5c 100644
--- a/src/H5FDlog.c
+++ b/src/H5FDlog.c
@@ -657,6 +657,7 @@ H5FD_log_query(const H5FD_t UNUSED *_f, unsigned long *flags /* out */)
*flags|=H5FD_FEAT_AGGREGATE_METADATA; /* OK to aggregate metadata allocations */
*flags|=H5FD_FEAT_ACCUMULATE_METADATA; /* OK to accumulate metadata for faster writes */
*flags|=H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */
+ *flags|=H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
}
FUNC_LEAVE(ret_value);
diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c
index fe7cfb1..6b4a20c 100644
--- a/src/H5FDmpio.c
+++ b/src/H5FDmpio.c
@@ -952,6 +952,7 @@ H5FD_mpio_query(const H5FD_t *_file, unsigned long *flags /* out */)
if(flags) {
*flags=0;
*flags|=H5FD_FEAT_AGGREGATE_METADATA; /* OK to aggregate metadata allocations */
+ *flags|=H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
} /* end if */
FUNC_LEAVE(ret_value);
diff --git a/src/H5FDmulti.c b/src/H5FDmulti.c
index c8773ff..48e711f 100644
--- a/src/H5FDmulti.c
+++ b/src/H5FDmulti.c
@@ -1359,6 +1359,7 @@ H5FD_multi_query(const H5FD_t *_f, unsigned long *flags /* out */)
if(flags) {
*flags=0;
*flags|=H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */
+ *flags|=H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
}
return(0);
diff --git a/src/H5FDpublic.h b/src/H5FDpublic.h
index 815a940..802b1c9 100644
--- a/src/H5FDpublic.h
+++ b/src/H5FDpublic.h
@@ -99,6 +99,12 @@ typedef enum H5FD_mem_t {
* http://www.mcs.anl.gov/~thakur/papers/mpio-high-perf.ps.gz
*/
#define H5FD_FEAT_DATA_SIEVE 0x00000004
+ /*
+ * Defining the H5FD_FEAT_AGGREGATE_SMALLDATA for a VFL driver means that
+ * the library will attempt to allocate a larger block for "small" raw data
+ * and then sub-allocate "small" raw data requests from that larger block.
+ */
+#define H5FD_FEAT_AGGREGATE_SMALLDATA 0x00000008
/* Forward declaration */
@@ -162,6 +168,11 @@ struct H5FD_t {
hsize_t cur_meta_block_size; /* Current size of metadata allocation region left */
haddr_t eoma; /* End of metadata allocated region */
+ /* "Small data" aggregation fields */
+ hsize_t def_sdata_block_size; /* "Small data" allocation block size (if aggregating "small data") */
+ hsize_t cur_sdata_block_size; /* Current size of "small data" allocation region left */
+ haddr_t eosda; /* End of "small data" allocated region */
+
/* Metadata accumulator fields */
unsigned char *meta_accum; /* Buffer to hold the accumulated metadata */
haddr_t accum_loc; /* File location (offset) of the accumulated metadata */
diff --git a/src/H5FDsec2.c b/src/H5FDsec2.c
index 06a5e49..85c5a31 100644
--- a/src/H5FDsec2.c
+++ b/src/H5FDsec2.c
@@ -430,6 +430,7 @@ H5FD_sec2_query(const H5FD_t UNUSED *_f, unsigned long *flags /* out */)
*flags|=H5FD_FEAT_AGGREGATE_METADATA; /* OK to aggregate metadata allocations */
*flags|=H5FD_FEAT_ACCUMULATE_METADATA; /* OK to accumulate metadata for faster writes */
*flags|=H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */
+ *flags|=H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
}
FUNC_LEAVE(ret_value);
diff --git a/src/H5FDsrb.c b/src/H5FDsrb.c
index ae7d447..21beb41 100644
--- a/src/H5FDsrb.c
+++ b/src/H5FDsrb.c
@@ -391,6 +391,7 @@ H5FD_srb_query(const UNUSED H5FD_t *_f, unsigned long *flags /* out */)
if(flags) {
*flags = 0;
*flags|=H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */
+ *flags|=H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
}
FUNC_LEAVE(ret_value);
diff --git a/src/H5FDstdio.c b/src/H5FDstdio.c
index 9569f8f..f748254 100644
--- a/src/H5FDstdio.c
+++ b/src/H5FDstdio.c
@@ -462,6 +462,7 @@ H5FD_stdio_query(const H5FD_t *_f, unsigned long *flags /* out */)
*flags|=H5FD_FEAT_AGGREGATE_METADATA; /* OK to aggregate metadata allocations */
*flags|=H5FD_FEAT_ACCUMULATE_METADATA; /* OK to accumulate metadata for faster writes */
*flags|=H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */
+ *flags|=H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
}
return(0);
diff --git a/src/H5FDstream.c b/src/H5FDstream.c
index fcbee7e..74db940 100644
--- a/src/H5FDstream.c
+++ b/src/H5FDstream.c
@@ -945,6 +945,7 @@ H5FD_stream_query(const H5FD_t UNUSED *_f,
*flags = 0;
/* OK to perform data sieving for faster raw data reads & writes */
*flags |= H5FD_FEAT_DATA_SIEVE;
+ *flags|=H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
}
FUNC_LEAVE (SUCCEED);
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 971cf2d..31ec3ba 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -241,6 +241,7 @@ typedef struct H5F_access_t {
hsize_t threshold; /* Threshold for alignment */
hsize_t alignment; /* Alignment */
size_t meta_block_size; /* Minimum metadata allocation block size (when aggregating metadata allocations) */
+ size_t sdata_block_size; /* Minimum "small data" allocation block size (when aggregating "small data" allocations) */
hsize_t sieve_buf_size; /* Maximum sieve buffer size (when data sieving is allowed by file driver) */
unsigned gc_ref; /* Garbage-collect references? */
hid_t driver_id; /* File driver ID */
diff --git a/src/H5P.c b/src/H5P.c
index f71537a..76ef5d0 100644
--- a/src/H5P.c
+++ b/src/H5P.c
@@ -3778,6 +3778,8 @@ H5Pget_vlen_mem_manager(hid_t plist_id, H5MM_allocate_t *alloc_func/*out*/,
* Friday, August 25, 2000
*
* Modifications:
+ * Quincey Koziol, June 5, 2002
+ * Also sets the "small data" aggregation size
*
*-------------------------------------------------------------------------
*/
@@ -3797,7 +3799,7 @@ H5Pset_meta_block_size(hid_t fapl_id, hsize_t size)
}
/* Set values */
- fapl->meta_block_size = size;
+ fapl->sdata_block_size = fapl->meta_block_size = size;
FUNC_LEAVE (SUCCEED);
}