Skip to content
This repository was archived by the owner on Feb 26, 2025. It is now read-only.

Commit 82fa9e3

Browse files
committed
Use aggregated reading for 1D selections.
Aggregating scattered reads was implemented in * 8366465 adds bulkRead, * a7d1453 for 2D selections. However, it was only used for edge indexes. We measured the performance on an HDD and SSD for random access patterns with different streak lengths. We found that for all cases, including streak length of 1, using bulkRead was preferrable over both `0.1.24` (using `HighFive::ElementSet`) and `0.1.29` (using `HighFive::HyperSlab`). We investigated if aggregating multiple pages was beneficial and found that it was not.
1 parent 588434f commit 82fa9e3

File tree

2 files changed

+15
-19
lines changed

2 files changed

+15
-19
lines changed

src/hdf5_reader.hpp

+1-6
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,7 @@ class Hdf5PluginRead1DDefault: virtual public Hdf5PluginRead1DInterface<T>
2828
public:
2929
std::vector<T> readSelection(const HighFive::DataSet& dset,
3030
const Selection& selection) const override {
31-
if (selection.ranges().empty()) {
32-
return {};
33-
}
34-
35-
return dset.select(detail::_makeHyperslab(selection.ranges()))
36-
.template read<std::vector<T>>();
31+
return detail::readCanonicalSelection<T>(dset, selection);
3732
}
3833
};
3934

src/read_canonical_selection.hpp

+14-13
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,26 @@ namespace bbp {
99
namespace sonata {
1010
namespace detail {
1111

12-
template <class Range>
13-
HighFive::HyperSlab make_hyperslab(const std::vector<Range>& ranges) {
14-
HighFive::HyperSlab slab;
15-
for (const auto& range : ranges) {
16-
size_t i_begin = std::get<0>(range);
17-
size_t i_end = std::get<1>(range);
18-
slab |= HighFive::RegularHyperSlab({i_begin}, {i_end - i_begin});
19-
}
20-
21-
return slab;
22-
}
23-
2412
template <class T>
2513
std::vector<T> readCanonicalSelection(const HighFive::DataSet& dset, const Selection& selection) {
2614
if (selection.empty()) {
2715
return {};
2816
}
2917

30-
return dset.select(make_hyperslab(selection.ranges())).template read<std::vector<T>>();
18+
constexpr size_t min_gap_size = SONATA_PAGESIZE / sizeof(T);
19+
constexpr size_t max_aggregated_block_size = 16 * min_gap_size;
20+
21+
auto readBlock = [&](auto& buffer, const auto& range) {
22+
size_t i_begin = std::get<0>(range);
23+
size_t i_end = std::get<1>(range);
24+
dset.select({i_begin}, {i_end - i_begin}).read(buffer);
25+
};
26+
27+
return bulk_read::bulkRead<T>([&readBlock](auto& buffer,
28+
const auto& range) { readBlock(buffer, range); },
29+
selection.ranges(),
30+
min_gap_size,
31+
max_aggregated_block_size);
3132
}
3233

3334
template <class T>

0 commit comments

Comments
 (0)