|
8 | 8 | #include <mutex> |
9 | 9 | #include <shared_mutex> |
10 | 10 | #include <stdexcept> |
| 11 | +#include <thread> |
11 | 12 | #include <vector> |
12 | 13 |
|
13 | 14 | #include "openvino/util/common_util.hpp" |
@@ -302,7 +303,7 @@ class MapHolder : public ov::MappedMemory { |
302 | 303 |
|
303 | 304 | void hint_evict(size_t offset, size_t size) noexcept override; |
304 | 305 |
|
305 | | - void hint_prefetch(size_t /*offset*/, size_t /*size*/) override {} |
| 306 | + void hint_prefetch(size_t offset, size_t size) override; |
306 | 307 |
|
307 | 308 | private: |
308 | 309 | /** |
@@ -743,6 +744,33 @@ bool MapHolder::try_remap_slot(uintptr_t fault_addr) { |
743 | 744 | return remap_placeholder(proc, placeholder_base, placeholder_size); |
744 | 745 | } |
745 | 746 |
|
| 747 | +namespace { |
| 748 | + |
| 749 | +// Clamps [offset, offset + size) to [0, mapping_size) and page-aligns the result. |
| 750 | +// Returns an empty region (m_length == 0) for a null/empty mapping, an offset at or past the end, |
| 751 | +// or a sub-page request. |
| 752 | +util::AlignedRegion clamp_align_region(const void* data, size_t mapping_size, size_t offset, size_t size) noexcept { |
| 753 | + const auto page_size = static_cast<size_t>(util::get_system_page_size()); |
| 754 | + if (data == nullptr || mapping_size == 0 || offset >= mapping_size || size < page_size) { |
| 755 | + return {}; |
| 756 | + } |
| 757 | + const auto available = mapping_size - offset; |
| 758 | + const auto raw_len = (size == auto_size) ? available : std::min(size, available); |
| 759 | + return util::align_region(reinterpret_cast<uintptr_t>(data) + offset, raw_len, page_size); |
| 760 | +} |
| 761 | + |
| 762 | +} // namespace |
| 763 | + |
| 764 | +void MapHolder::hint_prefetch(size_t offset, size_t size) { |
| 765 | + // Below 4 MiB the overhead of spawning threads exceeds the benefit; skip. |
| 766 | + if (const auto region = clamp_align_region(m_data, m_size, offset, size); region.m_length > 4 * util::one_mib) { |
| 767 | + const auto num_threads = std::min<size_t>(10, std::thread::hardware_concurrency()); |
| 768 | + const auto aligned_size = |
| 769 | + util::align_size_up(region.m_length, static_cast<size_t>(util::get_system_page_size())); |
| 770 | + util::vm_prefetch(reinterpret_cast<void*>(region.m_address), aligned_size, num_threads); |
| 771 | + } |
| 772 | +} |
| 773 | + |
746 | 774 | std::pair<char*, char*> MapHolder::compute_evict_range(size_t offset, size_t size) const noexcept { |
747 | 775 | // Require placeholder path, API availability, and a live VEH (eviction without VEH |
748 | 776 | // would leave inaccessible placeholders on the next access). |
|
0 commit comments