From 3d1489de593574e65ef1e64a7ae64e4e56c2978b Mon Sep 17 00:00:00 2001 From: Georgios Pinitas Date: Thu, 3 May 2018 20:47:16 +0100 Subject: COMPMID-605: Transition buffer memory manager Change-Id: Ide7c6124eb19f13f15f517e62d705646a0cd1ecd Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/130184 Reviewed-by: Georgios Pinitas Tested-by: Jenkins Reviewed-by: Anthony Barbier --- src/runtime/BlobLifetimeManager.cpp | 22 ++++++++----- src/runtime/ISimpleLifetimeManager.cpp | 57 +++++++++++++++++++++++----------- src/runtime/OffsetLifetimeManager.cpp | 17 ++++++---- 3 files changed, 64 insertions(+), 32 deletions(-) (limited to 'src/runtime') diff --git a/src/runtime/BlobLifetimeManager.cpp b/src/runtime/BlobLifetimeManager.cpp index 3ca5071d91..2a4ab6ec0d 100644 --- a/src/runtime/BlobLifetimeManager.cpp +++ b/src/runtime/BlobLifetimeManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2017-2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -57,15 +57,15 @@ void BlobLifetimeManager::update_blobs_and_mappings() ARM_COMPUTE_ERROR_ON(!are_all_finalized()); ARM_COMPUTE_ERROR_ON(_active_group == nullptr); - // Sort active group requirements in descending order. - std::sort(std::begin(_active_elements), std::end(_active_elements), [](const Element & a, const Element & b) + // Sort free blobs requirements in descending order. + _free_blobs.sort([](const Blob & ba, const Blob & bb) { - return a.size > b.size; + return ba.max_size > bb.max_size; }); std::vector group_sizes; - std::transform(std::begin(_active_elements), std::end(_active_elements), std::back_inserter(group_sizes), [](const Element & e) + std::transform(std::begin(_free_blobs), std::end(_free_blobs), std::back_inserter(group_sizes), [](const Blob & b) { - return e.size; + return b.max_size; }); // Update blob sizes @@ -80,8 +80,14 @@ void BlobLifetimeManager::update_blobs_and_mappings() // Calculate group mappings auto &group_mappings = _active_group->mappings(); int blob_idx = 0; - for(auto &e : _active_elements) + for(auto &free_blob : _free_blobs) { - group_mappings[e.handle] = blob_idx++; + for(auto &bound_element_id : free_blob.bound_elements) + { + ARM_COMPUTE_ERROR_ON(_active_elements.find(bound_element_id) == std::end(_active_elements)); + Element &bound_element = _active_elements[bound_element_id]; + group_mappings[bound_element.handle] = blob_idx; + } + ++blob_idx; } } diff --git a/src/runtime/ISimpleLifetimeManager.cpp b/src/runtime/ISimpleLifetimeManager.cpp index 2c64475b39..faaff8a63e 100644 --- a/src/runtime/ISimpleLifetimeManager.cpp +++ b/src/runtime/ISimpleLifetimeManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2017-2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -37,7 +37,7 @@ using namespace arm_compute; ISimpleLifetimeManager::ISimpleLifetimeManager() - : _active_group(nullptr), _active_elements(), _finalized_groups() + : _active_group(nullptr), _active_elements(), _free_blobs(), _occupied_blobs(), _finalized_groups() { } @@ -53,14 +53,21 @@ void ISimpleLifetimeManager::register_group(IMemoryGroup *group) void ISimpleLifetimeManager::start_lifetime(void *obj) { ARM_COMPUTE_ERROR_ON(obj == nullptr); - ARM_COMPUTE_ERROR_ON_MSG(std::find_if(std::begin(_active_elements), std::end(_active_elements), [&obj](const Element & e) + ARM_COMPUTE_ERROR_ON_MSG(_active_elements.find(obj) != std::end(_active_elements), "Memory object is already registered!"); + + // Check if there is a free blob + if(_free_blobs.empty()) + { + _occupied_blobs.emplace_front(Blob{ obj, 0, { obj } }); + } + else { - return obj == e.id; - }) != std::end(_active_elements), - "Memory object is already registered!"); + _occupied_blobs.splice(std::begin(_occupied_blobs), _free_blobs, std::begin(_free_blobs)); + _occupied_blobs.front().id = obj; + } // Insert object in groups and mark its finalized state to false - _active_elements.emplace_back(obj); + _active_elements.insert(std::make_pair(obj, obj)); } void ISimpleLifetimeManager::end_lifetime(void *obj, void **handle, size_t size) @@ -68,36 +75,50 @@ void ISimpleLifetimeManager::end_lifetime(void *obj, void **handle, size_t size) ARM_COMPUTE_ERROR_ON(obj == nullptr); // Find object - auto it = std::find_if(std::begin(_active_elements), std::end(_active_elements), [&obj](const Element & e) + auto active_object_it = _active_elements.find(obj); + ARM_COMPUTE_ERROR_ON(active_object_it == std::end(_active_elements)); + + // Update object fields and mark object as complete + Element &el = active_object_it->second; + el.handle = handle; + el.size = size; + el.status = true; + + // Find object in the occupied lists + auto occupied_blob_it = std::find_if(std::begin(_occupied_blobs), std::end(_occupied_blobs), [&obj](const Blob & b) { - return obj == e.id; + return obj == b.id; }); - ARM_COMPUTE_ERROR_ON(it == std::end(_active_elements)); + ARM_COMPUTE_ERROR_ON(occupied_blob_it == std::end(_occupied_blobs)); - // Update object fields and mark object as complete - it->handle = handle; - it->size = size; - it->status = true; + // Update occupied blob and return as free + occupied_blob_it->bound_elements.insert(obj); + occupied_blob_it->max_size = std::max(occupied_blob_it->max_size, size); + occupied_blob_it->id = nullptr; + _free_blobs.splice(std::begin(_free_blobs), _occupied_blobs, occupied_blob_it); // Check if all object are finalized and reset active group if(are_all_finalized()) { - // Update finalized groups - _finalized_groups[_active_group].insert(std::end(_finalized_groups[_active_group]), std::begin(_active_elements), std::end(_active_elements)); + ARM_COMPUTE_ERROR_ON(!_occupied_blobs.empty()); // Update blobs and group mappings update_blobs_and_mappings(); + // Update finalized groups + _finalized_groups[_active_group] = std::move(_active_elements); + // Reset state _active_elements.clear(); _active_group = nullptr; + _free_blobs.clear(); } } bool ISimpleLifetimeManager::are_all_finalized() const { - return !std::any_of(std::begin(_active_elements), std::end(_active_elements), [](const Element e) + return !std::any_of(std::begin(_active_elements), std::end(_active_elements), [](const std::pair &e) { - return !e.status; + return !e.second.status; }); } diff --git a/src/runtime/OffsetLifetimeManager.cpp b/src/runtime/OffsetLifetimeManager.cpp index 4540aeab28..d0b3bde724 100644 --- a/src/runtime/OffsetLifetimeManager.cpp +++ b/src/runtime/OffsetLifetimeManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2017-2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -58,19 +58,24 @@ void OffsetLifetimeManager::update_blobs_and_mappings() ARM_COMPUTE_ERROR_ON(_active_group == nullptr); // Update blob size - size_t max_group_size = std::accumulate(std::begin(_active_elements), std::end(_active_elements), static_cast(0), [](size_t s, const Element & e) + size_t max_group_size = std::accumulate(std::begin(_free_blobs), std::end(_free_blobs), static_cast(0), [](size_t s, const Blob & b) { - return s + e.size; + return s + b.max_size; }); _blob = std::max(_blob, max_group_size); // Calculate group mappings auto &group_mappings = _active_group->mappings(); size_t offset = 0; - for(auto &e : _active_elements) + for(auto &free_blob : _free_blobs) { - group_mappings[e.handle] = offset; - offset += e.size; + for(auto &bound_element_id : free_blob.bound_elements) + { + ARM_COMPUTE_ERROR_ON(_active_elements.find(bound_element_id) == std::end(_active_elements)); + Element &bound_element = _active_elements[bound_element_id]; + group_mappings[bound_element.handle] = offset; + } + offset += free_blob.max_size; ARM_COMPUTE_ERROR_ON(offset > _blob); } } -- cgit v1.2.1