summaryrefslogtreecommitdiffstats
path: root/src/H5Defl.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2010-10-01 05:39:05 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2010-10-01 05:39:05 (GMT)
commitdc4756fbf47d8fe84472269f24cedc16c8093c48 (patch)
tree6cc8a9172767ebdbf4cc73c8db5b95b8e7aa4f88 /src/H5Defl.c
parente171b57b999a4d0b6c0b97c8138880056fc4a956 (diff)
downloadhdf5-dc4756fbf47d8fe84472269f24cedc16c8093c48.zip
hdf5-dc4756fbf47d8fe84472269f24cedc16c8093c48.tar.gz
hdf5-dc4756fbf47d8fe84472269f24cedc16c8093c48.tar.bz2
[svn-r19498] Description:
Optimize the vector-vector memcpy() routine even further, for a total of ~2x speedup. :-) Make a generic vector-vector operation routine and convert other vector-vector read & write routines to use generic routine instead of multiple copies of the basic algorithm. Tested on: FreeBSD/32 6.3 (duty) in debug mode FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (jam) w/PGI compilers, w/default API=1.8.x, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (amani) w/Intel compilers, w/default API=1.6.x, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, w/threadsafe, in production mode Linux/PPC 2.6 (heiwa) w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in debug mode Mac OS X/32 10.6.4 (amazon) in debug mode Mac OS X/32 10.6.4 (amazon) w/C++ & FORTRAN, w/threadsafe, in production mode Mac OS X/32 10.6.4 (amazon) w/parallel, in debug mode
Diffstat (limited to 'src/H5Defl.c')
-rw-r--r--src/H5Defl.c212
1 files changed, 114 insertions, 98 deletions
diff --git a/src/H5Defl.c b/src/H5Defl.c
index 87471f1..bcb47a2 100644
--- a/src/H5Defl.c
+++ b/src/H5Defl.c
@@ -33,6 +33,7 @@
#include "H5Eprivate.h" /* Error handling */
#include "H5Fprivate.h" /* Files */
#include "H5HLprivate.h" /* Local Heaps */
+#include "H5Vprivate.h" /* Vector and array functions */
/****************/
@@ -44,6 +45,18 @@
/* Local Typedefs */
/******************/
+/* Callback info for readvv operation */
+typedef struct H5D_efl_readvv_ud_t {
+ const H5O_efl_t *efl; /* Pointer to efl info */
+ unsigned char *rbuf; /* Read buffer */
+} H5D_efl_readvv_ud_t;
+
+/* Callback info for writevv operation */
+typedef struct H5D_efl_writevv_ud_t {
+ const H5O_efl_t *efl; /* Pointer to efl info */
+ const unsigned char *wbuf; /* Write buffer */
+} H5D_efl_writevv_ud_t;
+
/********************/
/* Local Prototypes */
@@ -398,6 +411,35 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5D_efl_readvv_cb
+ *
+ * Purpose: Callback operator for H5D_efl_readvv().
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, Sept 30, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_efl_readvv_cb(hsize_t dst_off, hsize_t src_off, size_t len, void *_udata)
+{
+ H5D_efl_readvv_ud_t *udata = (H5D_efl_readvv_ud_t *)_udata; /* User data for H5V_opvv() operator */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5D_efl_readvv_cb)
+
+ /* Read data */
+ if(H5D_efl_read(udata->efl, dst_off, len, (udata->rbuf + src_off)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "EFL read failed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_efl_readvv_cb() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5D_efl_readvv
*
* Purpose: Reads data from an external file list. It is an error to
@@ -414,65 +456,67 @@ done:
*/
static ssize_t
H5D_efl_readvv(const H5D_io_info_t *io_info,
- size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
- size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[])
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_off_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_off_arr[])
{
- const H5O_efl_t *efl = &(io_info->store->efl); /* Pointer to efl info */
- unsigned char *buf; /* Pointer to buffer to write */
- haddr_t addr; /* Actual address to read */
- size_t size; /* Size of sequence in bytes */
- size_t u, v; /* Counting variables */
- ssize_t ret_value = 0; /* Return value (Total size of sequence in bytes) */
+ H5D_efl_readvv_ud_t udata; /* User data for H5V_opvv() operator */
+ ssize_t ret_value; /* Return value (Total size of sequence in bytes) */
FUNC_ENTER_NOAPI_NOINIT(H5D_efl_readvv)
/* Check args */
- HDassert(efl && efl->nused > 0);
+ HDassert(io_info);
+ HDassert(io_info->store->efl.nused > 0);
HDassert(io_info->u.rbuf);
+ HDassert(dset_curr_seq);
+ HDassert(dset_len_arr);
+ HDassert(dset_off_arr);
+ HDassert(mem_curr_seq);
+ HDassert(mem_len_arr);
+ HDassert(mem_off_arr);
+
+ /* Set up user data for H5V_opvv() */
+ udata.efl = &(io_info->store->efl);
+ udata.rbuf = (unsigned char *)io_info->u.rbuf;
+
+ /* Call generic sequence operation routine */
+ if((ret_value = H5V_opvv(dset_max_nseq, dset_curr_seq, dset_len_arr, dset_off_arr,
+ mem_max_nseq, mem_curr_seq, mem_len_arr, mem_off_arr,
+ H5D_efl_readvv_cb, &udata)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTOPERATE, FAIL, "can't perform vectorized EFL read")
- /* Work through all the sequences */
- for(u = *dset_curr_seq, v = *mem_curr_seq; u < dset_max_nseq && v < mem_max_nseq; ) {
- /* Choose smallest buffer to write */
- if(mem_len_arr[v] < dset_len_arr[u])
- size = mem_len_arr[v];
- else
- size = dset_len_arr[u];
-
- /* Compute offset on disk */
- addr = dset_offset_arr[u];
-
- /* Compute offset in memory */
- buf = (unsigned char *)io_info->u.rbuf + mem_offset_arr[v];
-
- /* Read data */
- if(H5D_efl_read(efl, addr, size, buf) < 0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed")
-
- /* Update memory information */
- mem_len_arr[v] -= size;
- if(mem_len_arr[v] == 0)
- v++;
- else
- mem_offset_arr[v] += size;
-
- /* Update file information */
- dset_len_arr[u] -= size;
- if(dset_len_arr[u] == 0)
- u++;
- else
- dset_offset_arr[u] += size;
-
- /* Increment number of bytes copied */
- ret_value += (ssize_t)size;
- } /* end for */
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_efl_readvv() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_efl_writevv_cb
+ *
+ * Purpose: Callback operator for H5D_efl_writevv().
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, Sept 30, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_efl_writevv_cb(hsize_t dst_off, hsize_t src_off, size_t len, void *_udata)
+{
+ H5D_efl_writevv_ud_t *udata = (H5D_efl_writevv_ud_t *)_udata; /* User data for H5V_opvv() operator */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5D_efl_writevv_cb)
- /* Update current sequence vectors */
- *dset_curr_seq = u;
- *mem_curr_seq = v;
+ /* Write data */
+ if(H5D_efl_write(udata->efl, dst_off, len, (udata->wbuf + src_off)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "EFL write failed")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D_efl_readvv() */
+} /* end H5D_efl_writevv_cb() */
/*-------------------------------------------------------------------------
@@ -492,62 +536,34 @@ done:
*/
static ssize_t
H5D_efl_writevv(const H5D_io_info_t *io_info,
- size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
- size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[])
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_off_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_off_arr[])
{
- const H5O_efl_t *efl = &(io_info->store->efl); /* Pointer to efl info */
- const unsigned char *buf; /* Pointer to buffer to write */
- haddr_t addr; /* Actual address to read */
- size_t size; /* Size of sequence in bytes */
- size_t u, v; /* Counting variables */
- ssize_t ret_value = 0; /* Return value (Total size of sequence in bytes) */
+ H5D_efl_writevv_ud_t udata; /* User data for H5V_opvv() operator */
+ ssize_t ret_value; /* Return value (Total size of sequence in bytes) */
FUNC_ENTER_NOAPI_NOINIT(H5D_efl_writevv)
/* Check args */
- HDassert(efl && efl->nused > 0);
+ HDassert(io_info);
+ HDassert(io_info->store->efl.nused > 0);
HDassert(io_info->u.wbuf);
-
- /* Work through all the sequences */
- for(u = *dset_curr_seq, v = *mem_curr_seq; u < dset_max_nseq && v < mem_max_nseq; ) {
- /* Choose smallest buffer to write */
- if(mem_len_arr[v] < dset_len_arr[u])
- size = mem_len_arr[v];
- else
- size = dset_len_arr[u];
-
- /* Compute offset on disk */
- addr = dset_offset_arr[u];
-
- /* Compute offset in memory */
- buf = (const unsigned char *)io_info->u.wbuf + mem_offset_arr[v];
-
- /* Write data */
- if(H5D_efl_write(efl, addr, size, buf) < 0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed")
-
- /* Update memory information */
- mem_len_arr[v] -= size;
- if(mem_len_arr[v] == 0)
- v++;
- else
- mem_offset_arr[v] += size;
-
- /* Update file information */
- dset_len_arr[u] -= size;
- if(dset_len_arr[u] == 0)
- u++;
- else
- dset_offset_arr[u] += size;
-
- /* Increment number of bytes copied */
- ret_value += (ssize_t)size;
- } /* end for */
-
- /* Update current sequence vectors */
- *dset_curr_seq = u;
- *mem_curr_seq = v;
-
+ HDassert(dset_curr_seq);
+ HDassert(dset_len_arr);
+ HDassert(dset_off_arr);
+ HDassert(mem_curr_seq);
+ HDassert(mem_len_arr);
+ HDassert(mem_off_arr);
+
+ /* Set up user data for H5V_opvv() */
+ udata.efl = &(io_info->store->efl);
+ udata.wbuf = (const unsigned char *)io_info->u.wbuf;
+
+ /* Call generic sequence operation routine */
+ if((ret_value = H5V_opvv(dset_max_nseq, dset_curr_seq, dset_len_arr, dset_off_arr,
+ mem_max_nseq, mem_curr_seq, mem_len_arr, mem_off_arr,
+ H5D_efl_writevv_cb, &udata)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTOPERATE, FAIL, "can't perform vectorized EFL write")
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_efl_writevv() */