diff options
author | Raymond Lu <songyulu@hdfgroup.org> | 2007-05-23 22:43:03 (GMT) |
---|---|---|
committer | Raymond Lu <songyulu@hdfgroup.org> | 2007-05-23 22:43:03 (GMT) |
commit | b08afe35a41fc89bfa2d4ad7d412b4c91a25dacf (patch) | |
tree | 14ff26ad10720a34558903ec043654add993cc14 /src | |
parent | 1d17ae7d699103fcf6d79b3c52915b4e9ca8f9f0 (diff) | |
download | hdf5-b08afe35a41fc89bfa2d4ad7d412b4c91a25dacf.zip hdf5-b08afe35a41fc89bfa2d4ad7d412b4c91a25dacf.tar.gz hdf5-b08afe35a41fc89bfa2d4ad7d412b4c91a25dacf.tar.bz2 |
[svn-r13803] Optimization of reading compound data.
Optimize a special case when the source members are a subset of
destination, and the order is the same, and no conversion is needed.
For example:
struct source { struct destination {
TYPE1 A; --> TYPE1 A;
TYPE2 B; --> TYPE2 B;
TYPE3 C; --> TYPE3 C;
}; TYPE4 D;
TYPE5 E;
};
The optimization is simply moving data to the appropriate
places in the buffer. This optimization work is for the Chicago company.
Tested on sol, copper, smirom, liberty.
Diffstat (limited to 'src')
-rw-r--r-- | src/H5Tconv.c | 198 |
1 files changed, 139 insertions, 59 deletions
diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 3a94bb2..f2b410e 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -35,6 +35,7 @@ typedef struct H5T_conv_struct_t { hid_t *src_memb_id; /*source member type ID's */ hid_t *dst_memb_id; /*destination member type ID's */ H5T_path_t **memb_path; /*conversion path for each member */ + hbool_t smembs_subset; /*are source members a subset and in the top of dest? */ } H5T_conv_struct_t; /* Conversion data for H5T_conv_enum() */ @@ -1701,7 +1702,20 @@ done: * Monday, January 26, 1998 * * Modifications: - * + * Raymond Lu, 3 May 2007 + * Added the detection for a special optimization case when the + * source members are a subset of destination, and the order is + * the same, and no conversion is needed. For example: + * struct source { struct destination { + * TYPE1 A; --> TYPE1 A; + * TYPE2 B; --> TYPE2 B; + * TYPE3 C; --> TYPE3 C; + * }; TYPE4 D; + * TYPE5 E; + * }; + * The optimization is simply moving data to the appropriate + * places in the buffer. + * *------------------------------------------------------------------------- */ static herr_t @@ -1730,6 +1744,10 @@ H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata, hid_t dxpl_id) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); src2dst = priv->src2dst; + /* The flag of special optimization to indicate if source members are a subset + * and in the top of the destination. Initialize it to TRUE */ + priv->smembs_subset = TRUE; + /* * Insure that members are sorted. */ @@ -1764,6 +1782,11 @@ H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata, hid_t dxpl_id) assert (tid>=0); priv->dst_memb_id[src2dst[i]] = tid; } + + /* If any of source member doesn't have counterpart in the same order, + * don't do the special optimization. */ + if(src2dst[i] != i || (src->shared->u.compnd.memb[i].offset != dst->shared->u.compnd.memb[i].offset)) + priv->smembs_subset = FALSE; } } else { @@ -1796,6 +1819,11 @@ H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata, hid_t dxpl_id) cdata->priv = priv = H5MM_xfree (priv); HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unable to convert member data type"); } + + /* If any of source member needs conversion, don't do the special optimization. */ + if(priv->smembs_subset && ((priv->memb_path[i])->is_noop == FALSE)) + priv->smembs_subset = FALSE; + } } @@ -2003,9 +2031,9 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, xbkg += bkg_stride; } - /* If the bkg_stride was set to -(dst->shared->size), make it positive now */ - if(buf_stride==0 && dst->shared->size>src->shared->size) - bkg_stride=dst->shared->size; + /* If the bkg_stride was set to -(dst->shared->size), make it positive now */ + if(buf_stride==0 && dst->shared->size>src->shared->size) + bkg_stride=dst->shared->size; /* * Copy the background buffer back into the in-place conversion @@ -2079,6 +2107,21 @@ done: * multiple of BKG_STRIDE in the BKG buffer; otherwise the * BKG buffer is assumed to be a packed array of destination * datatype. + * + * Raymond Lu, 3 May 2007 + * Optimize a special case when the source members are a subset of + * destination, and the order is the same, and no conversion is needed. + * For example: + * struct source { struct destination { + * TYPE1 A; --> TYPE1 A; + * TYPE2 B; --> TYPE2 B; + * TYPE3 C; --> TYPE3 C; + * }; TYPE4 D; + * TYPE5 E; + * }; + * The optimization is simply moving data to the appropriate + * places in the buffer. + * *------------------------------------------------------------------------- */ herr_t @@ -2098,9 +2141,10 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t offset; /*byte offset wrt struct */ size_t elmtno; /*element counter */ unsigned u; /*counters */ - int i; /*counters */ + int i; /*counters */ H5T_conv_struct_t *priv = NULL; /*private data */ - herr_t ret_value=SUCCEED; /* Return value */ + hbool_t no_stride = FALSE; /*flag to indicate no stride */ + herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5T_conv_struct_opt, FAIL); @@ -2208,79 +2252,115 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, * otherwise assume BKG buffer is the packed destination datatype. */ if (!buf_stride || !bkg_stride) bkg_stride = dst->shared->size; + if (!buf_stride) { + no_stride = TRUE; + buf_stride = src->shared->size; + } - /* - * For each member where the destination is not larger than the - * source, stride through all the elements converting only that member - * in each element and then copying the element to its final - * destination in the bkg buffer. Otherwise move the element as far - * left as possible in the buffer. - */ - for (u=0, offset=0; u<src->shared->u.compnd.nmembs; u++) { - if (src2dst[u]<0) continue; /*subsetting*/ - src_memb = src->shared->u.compnd.memb + u; - dst_memb = dst->shared->u.compnd.memb + src2dst[u]; - - if (dst_memb->size <= src_memb->size) { - xbuf = buf + src_memb->offset; - xbkg = bkg + dst_memb->offset; - if (H5T_convert(priv->memb_path[u], - priv->src_memb_id[u], - priv->dst_memb_id[src2dst[u]], nelmts, - buf_stride ? buf_stride : src->shared->size, - bkg_stride, xbuf, xbkg, - dxpl_id)<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert compound data type member"); + if(priv->smembs_subset == TRUE) { + /* If the optimization flag is set to indicate source members are a subset and + * in the top of the destination, simply copy the source members to background buffer. */ + xbuf = buf; + xbkg = bkg; + if(dst->shared->size <= src->shared->size) { + /* This is to deal with a very special situation when the fields and their + * offset for both source and destination are identical but the datatype + * sizes of source and destination are different. The library still + * considers these two types different and does conversion. It happens + * in table API test (hdf5/hl/test/test_table.c) when a table field is + * deleted. + */ for (elmtno=0; elmtno<nelmts; elmtno++) { - HDmemmove(xbkg, xbuf, dst_memb->size); - xbuf += buf_stride ? buf_stride : src->shared->size; + HDmemmove(xbkg, xbuf, dst->shared->size); + + /* Update pointers */ + xbuf += buf_stride; xbkg += bkg_stride; } } else { - for (xbuf=buf, elmtno=0; elmtno<nelmts; elmtno++) { - HDmemmove(xbuf+offset, xbuf+src_memb->offset, + for (elmtno=0; elmtno<nelmts; elmtno++) { + HDmemmove(xbkg, xbuf, src->shared->size); + + /* Update pointers */ + xbuf += buf_stride; + xbkg += bkg_stride; + } + } + } else { + /* + * For each member where the destination is not larger than the + * source, stride through all the elements converting only that member + * in each element and then copying the element to its final + * destination in the bkg buffer. Otherwise move the element as far + * left as possible in the buffer. + */ + for (u=0, offset=0; u<src->shared->u.compnd.nmembs; u++) { + if (src2dst[u]<0) continue; /*subsetting*/ + src_memb = src->shared->u.compnd.memb + u; + dst_memb = dst->shared->u.compnd.memb + src2dst[u]; + + if (dst_memb->size <= src_memb->size) { + xbuf = buf + src_memb->offset; + xbkg = bkg + dst_memb->offset; + if (H5T_convert(priv->memb_path[u], + priv->src_memb_id[u], + priv->dst_memb_id[src2dst[u]], nelmts, + buf_stride, bkg_stride, xbuf, xbkg, dxpl_id)<0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert compound data type member"); + for (elmtno=0; elmtno<nelmts; elmtno++) { + HDmemmove(xbkg, xbuf, dst_memb->size); + xbuf += buf_stride; + xbkg += bkg_stride; + } + } else { + for (xbuf=buf, elmtno=0; elmtno<nelmts; elmtno++) { + HDmemmove(xbuf+offset, xbuf+src_memb->offset, src_memb->size); - xbuf += buf_stride ? buf_stride : src->shared->size; + xbuf += buf_stride; + } + offset += src_memb->size; } - offset += src_memb->size; } - } - /* - * Work from right to left, converting those members that weren't - * converted in the previous loop (those members where the destination - * is larger than the source) and them to their final position in the - * bkg buffer. - */ - for (i=src->shared->u.compnd.nmembs-1; i>=0; --i) { - if (src2dst[i]<0) - continue; - src_memb = src->shared->u.compnd.memb + i; - dst_memb = dst->shared->u.compnd.memb + src2dst[i]; - - if (dst_memb->size > src_memb->size) { - offset -= src_memb->size; - xbuf = buf + offset; - xbkg = bkg + dst_memb->offset; - if (H5T_convert(priv->memb_path[i], + /* + * Work from right to left, converting those members that weren't + * converted in the previous loop (those members where the destination + * is larger than the source) and them to their final position in the + * bkg buffer. + */ + for (i=src->shared->u.compnd.nmembs-1; i>=0; --i) { + if (src2dst[i]<0) + continue; + src_memb = src->shared->u.compnd.memb + i; + dst_memb = dst->shared->u.compnd.memb + src2dst[i]; + + if (dst_memb->size > src_memb->size) { + offset -= src_memb->size; + xbuf = buf + offset; + xbkg = bkg + dst_memb->offset; + if (H5T_convert(priv->memb_path[i], priv->src_memb_id[i], priv->dst_memb_id[src2dst[i]], nelmts, - buf_stride ? buf_stride : src->shared->size, + buf_stride, bkg_stride, xbuf, xbkg, dxpl_id)<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert compound data type member"); - for (elmtno=0; elmtno<nelmts; elmtno++) { - HDmemmove(xbkg, xbuf, dst_memb->size); - xbuf += buf_stride ? buf_stride : src->shared->size; - xbkg += bkg_stride; + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert compound data type member"); + for (elmtno=0; elmtno<nelmts; elmtno++) { + HDmemmove(xbkg, xbuf, dst_memb->size); + xbuf += buf_stride; + xbkg += bkg_stride; + } } } } + if(no_stride) + buf_stride = dst->shared->size; + /* Move background buffer into result buffer */ for (xbuf=buf, xbkg=bkg, elmtno=0; elmtno<nelmts; elmtno++) { HDmemmove(xbuf, xbkg, dst->shared->size); - xbuf += buf_stride ? buf_stride : dst->shared->size; + xbuf += buf_stride; xbkg += bkg_stride; } break; |