summaryrefslogtreecommitdiffstats
path: root/src/H5Sselect.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2000-09-13 21:58:18 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2000-09-13 21:58:18 (GMT)
commit1f109221dffd39ca93470923b32eb2a13ccb5715 (patch)
tree296f00b85e2aab5c5100a585af8074525b4fd1d6 /src/H5Sselect.c
parent683a11a633bb78695714f981d40a0265fdd81154 (diff)
downloadhdf5-1f109221dffd39ca93470923b32eb2a13ccb5715.zip
hdf5-1f109221dffd39ca93470923b32eb2a13ccb5715.tar.gz
hdf5-1f109221dffd39ca93470923b32eb2a13ccb5715.tar.bz2
[svn-r2544] Optimized regular hyperslab I/O routines and data structures. On my benchmarks,
they are about 4-5 times faster than before. We no longer generate "general" hyperslab data structures for regular hyperslabs, the general data structures are only generated when needed for irregular hyperslabs. Still fixing a couple of nook-and-cranny functions to understand the new information for the regular hyperslabs, so the tests aren't completely passing, but I wanted to get this checked in for Elena's benchmarks. I should have more/all tests passing later today.
Diffstat (limited to 'src/H5Sselect.c')
-rw-r--r--src/H5Sselect.c138
1 files changed, 119 insertions, 19 deletions
diff --git a/src/H5Sselect.c b/src/H5Sselect.c
index 4c80cb3..08f3752 100644
--- a/src/H5Sselect.c
+++ b/src/H5Sselect.c
@@ -590,12 +590,20 @@ static hssize_t
H5S_get_select_hyper_nblocks(H5S_t *space)
{
hssize_t ret_value=FAIL; /* return value */
+ intn i; /* Counter */
FUNC_ENTER (H5S_get_select_hyper_nblocks, FAIL);
assert(space);
- ret_value = (hssize_t)space->select.sel_info.hslab.hyper_lst->count;
+ /* Check for a "regular" hyperslab selection */
+ if(space->select.sel_info.hslab.diminfo != NULL) {
+ /* Check each dimension */
+ for(ret_value=1,i=0; i<space->extent.u.simple.rank; i++)
+ ret_value*=space->select.sel_info.hslab.diminfo[i].count;
+ } /* end if */
+ else
+ ret_value = (hssize_t)space->select.sel_info.hslab.hyper_lst->count;
FUNC_LEAVE (ret_value);
} /* H5Sget_select_hyper_nblocks() */
@@ -742,8 +750,17 @@ H5Sget_select_elem_npoints(hid_t spaceid)
static herr_t
H5S_get_select_hyper_blocklist(H5S_t *space, hsize_t startblock, hsize_t numblocks, hsize_t *buf)
{
+ H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */
+ hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary hyperslab counts */
+ hssize_t offset[H5O_LAYOUT_NDIMS]; /* Offset of element in dataspace */
+ size_t temp_off; /* Offset in a given dimension */
H5S_hyper_node_t *node; /* Hyperslab node */
intn rank; /* Dataspace rank */
+ intn i; /* Counter */
+ intn fast_dim; /* Rank of the fastest changing dimension for the dataspace */
+ intn temp_dim; /* Temporary rank holder */
+ intn ndims; /* Rank of the dataspace */
+ intn done; /* Whether we are done with the iteration */
herr_t ret_value=SUCCEED; /* return value */
FUNC_ENTER (H5S_get_select_hyper_blocklist, FAIL);
@@ -754,24 +771,107 @@ H5S_get_select_hyper_blocklist(H5S_t *space, hsize_t startblock, hsize_t numbloc
/* Get the dataspace extent rank */
rank=space->extent.u.simple.rank;
- /* Get the head of the hyperslab list */
- node=space->select.sel_info.hslab.hyper_lst->head;
-
- /* Get to the correct first node to give back to the user */
- while(node!=NULL && startblock>0) {
- startblock--;
- node=node->next;
- } /* end while */
-
- /* Iterate through the node, copying each hyperslab's information */
- while(node!=NULL && numblocks>0) {
- HDmemcpy(buf,node->start,sizeof(hsize_t)*rank);
- buf+=rank;
- HDmemcpy(buf,node->end,sizeof(hsize_t)*rank);
- buf+=rank;
- numblocks--;
- node=node->next;
- } /* end while */
+ /* Check for a "regular" hyperslab selection */
+ if(space->select.sel_info.hslab.diminfo != NULL) {
+ /* Set some convienence values */
+ ndims=space->extent.u.simple.rank;
+ fast_dim=ndims-1;
+ diminfo=space->select.sel_info.hslab.diminfo;
+
+ /* Build the tables of count sizes as well as the initial offset */
+ for(i=0; i<ndims; i++) {
+ tmp_count[i]=diminfo[i].count;
+ offset[i]=diminfo[i].start;
+ } /* end for */
+
+ /* We're not done with the iteration */
+ done=0;
+
+ /* Go iterate over the hyperslabs */
+ while(done==0 && numblocks>0) {
+ /* Iterate over the blocks in the fastest dimension */
+ while(tmp_count[fast_dim]>0 && numblocks>0) {
+
+ /* Check if we should copy this block information */
+ if(startblock==0) {
+ /* Copy the starting location */
+ HDmemcpy(buf,offset,sizeof(hsize_t)*ndims);
+ buf+=ndims;
+
+ /* Compute the ending location */
+ HDmemcpy(buf,offset,sizeof(hsize_t)*ndims);
+ for(i=0; i<ndims; i++)
+ buf[i]+=(diminfo[i].block-1);
+ buf+=ndims;
+
+ /* Decrement the number of blocks to retrieve */
+ numblocks--;
+ } /* end if */
+ else
+ startblock--;
+
+ /* Move the offset to the next sequence to start */
+ offset[fast_dim]+=diminfo[fast_dim].stride;
+
+ /* Decrement the block count */
+ tmp_count[fast_dim]--;
+ } /* end while */
+
+ /* Work on other dimensions if necessary */
+ if(fast_dim>0 && numblocks>0) {
+ /* Reset the block counts */
+ tmp_count[fast_dim]=diminfo[fast_dim].count;
+
+ /* Bubble up the decrement to the slower changing dimensions */
+ temp_dim=fast_dim-1;
+ while(temp_dim>=0 && done==0) {
+ /* Decrement the block count */
+ tmp_count[temp_dim]--;
+
+ /* Check if we have more blocks left */
+ if(tmp_count[temp_dim]>0)
+ break;
+
+ /* Check for getting out of iterator */
+ if(temp_dim==0)
+ done=1;
+
+ /* Reset the block count in this dimension */
+ tmp_count[temp_dim]=diminfo[temp_dim].count;
+
+ /* Wrapped a dimension, go up to next dimension */
+ temp_dim--;
+ } /* end while */
+ } /* end if */
+
+ /* Re-compute offset array */
+ for(i=0; i<ndims; i++) {
+ temp_off=diminfo[i].start
+ +diminfo[i].stride*(diminfo[i].count-tmp_count[i]);
+ offset[i]=temp_off;
+ } /* end for */
+ } /* end while */
+ } /* end if */
+ else {
+ /* Get the head of the hyperslab list */
+ node=space->select.sel_info.hslab.hyper_lst->head;
+
+ /* Get to the correct first node to give back to the user */
+ while(node!=NULL && startblock>0) {
+ startblock--;
+ node=node->next;
+ } /* end while */
+
+ /* Iterate through the node, copying each hyperslab's information */
+ while(node!=NULL && numblocks>0) {
+ HDmemcpy(buf,node->start,sizeof(hsize_t)*rank);
+ buf+=rank;
+ HDmemcpy(buf,node->end,sizeof(hsize_t)*rank);
+ buf+=rank;
+ numblocks--;
+ node=node->next;
+ } /* end while */
+ } /* end else */
FUNC_LEAVE (ret_value);
} /* H5Sget_select_hyper_blocklist() */