mirror of
https://github.com/intel/compute-runtime.git
synced 2025-09-15 13:01:45 +08:00
Class for local memory bank selection based on usage
Related-To: NEO-2906 Change-Id: I8b9cae5191da6344ee8d4f0cf7125f95d0bc6b35 Signed-off-by: Pawel Wilma <pawel.wilma@intel.com>
This commit is contained in:
@ -27,6 +27,8 @@ set(RUNTIME_SRCS_MEMORY_MANAGER
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/host_ptr_manager.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/internal_allocation_storage.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/internal_allocation_storage.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/local_memory_usage.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/local_memory_usage.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/memory_banks.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/memory_constants.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/memory_manager.cpp
|
||||
|
38
runtime/memory_manager/local_memory_usage.cpp
Normal file
38
runtime/memory_manager/local_memory_usage.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "runtime/memory_manager/local_memory_usage.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
namespace NEO {
|
||||
|
||||
LocalMemoryUsageBankSelector::LocalMemoryUsageBankSelector(uint32_t banksCount) : banksCount(banksCount) {
|
||||
UNRECOVERABLE_IF(banksCount == 0);
|
||||
|
||||
memorySizes.reset(new std::atomic<uint64_t>[banksCount]);
|
||||
for (uint32_t i = 0; i < banksCount; i++) {
|
||||
memorySizes[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t LocalMemoryUsageBankSelector::getLeastOccupiedBank() {
|
||||
auto leastOccupiedBankIterator = std::min_element(memorySizes.get(), memorySizes.get() + banksCount);
|
||||
return static_cast<uint32_t>(std::distance(memorySizes.get(), leastOccupiedBankIterator));
|
||||
}
|
||||
|
||||
void LocalMemoryUsageBankSelector::freeOnBank(uint32_t bankIndex, uint64_t allocationSize) {
|
||||
UNRECOVERABLE_IF(bankIndex >= banksCount);
|
||||
memorySizes[bankIndex] -= allocationSize;
|
||||
}
|
||||
void LocalMemoryUsageBankSelector::reserveOnBank(uint32_t bankIndex, uint64_t allocationSize) {
|
||||
UNRECOVERABLE_IF(bankIndex >= banksCount);
|
||||
memorySizes[bankIndex] += allocationSize;
|
||||
}
|
||||
|
||||
} // namespace NEO
|
34
runtime/memory_manager/local_memory_usage.h
Normal file
34
runtime/memory_manager/local_memory_usage.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "runtime/helpers/debug_helpers.h"
|
||||
#include "runtime/helpers/properties_helper.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
|
||||
namespace NEO {
|
||||
class LocalMemoryUsageBankSelector : public NonCopyableOrMovableClass {
|
||||
public:
|
||||
LocalMemoryUsageBankSelector() = delete;
|
||||
LocalMemoryUsageBankSelector(uint32_t banksCount);
|
||||
uint32_t getLeastOccupiedBank();
|
||||
void freeOnBank(uint32_t bankIndex, uint64_t allocationSize);
|
||||
void reserveOnBank(uint32_t bankIndex, uint64_t allocationSize);
|
||||
|
||||
MOCKABLE_VIRTUAL uint64_t getOccupiedMemorySizeForBank(uint32_t bankIndex) {
|
||||
UNRECOVERABLE_IF(bankIndex >= banksCount);
|
||||
return memorySizes[bankIndex].load();
|
||||
}
|
||||
|
||||
protected:
|
||||
uint32_t banksCount = 0;
|
||||
std::unique_ptr<std::atomic<uint64_t>[]> memorySizes = nullptr;
|
||||
};
|
||||
} // namespace NEO
|
@ -13,6 +13,7 @@ set(IGDRCL_SRCS_tests_memory_manager
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/graphics_allocation_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/host_ptr_manager_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/internal_allocation_storage_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/local_memory_usage_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/memory_manager_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}/memory_manager_allocate_in_device_pool_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/memory_manager_allocate_in_device_pool_tests.inl
|
||||
|
87
unit_tests/memory_manager/local_memory_usage_tests.cpp
Normal file
87
unit_tests/memory_manager/local_memory_usage_tests.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "runtime/helpers/basic_math.h"
|
||||
#include "runtime/memory_manager/local_memory_usage.h"
|
||||
|
||||
#include "third_party/gtest/gtest/gtest.h"
|
||||
|
||||
namespace NEO {
|
||||
|
||||
struct MockLocalMemoryUsageBankSelector : public LocalMemoryUsageBankSelector {
|
||||
using LocalMemoryUsageBankSelector::banksCount;
|
||||
using LocalMemoryUsageBankSelector::LocalMemoryUsageBankSelector;
|
||||
std::atomic<uint64_t> *getMemorySizes() { return memorySizes.get(); }
|
||||
};
|
||||
|
||||
TEST(localMemoryUsageTest, givenLocalMemoryUsageBankSelectorWhenItsCreatedAllValuesAreZero) {
|
||||
MockLocalMemoryUsageBankSelector selector(2u);
|
||||
|
||||
for (uint32_t i = 0; i < selector.banksCount; i++) {
|
||||
EXPECT_EQ(0u, selector.getMemorySizes()[i].load());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(localMemoryUsageTest, givenLocalMemoryUsageBankSelectorWhenMemoryIsReservedOnGivenBankThenValueStoredInTheArrayIsCorrect) {
|
||||
LocalMemoryUsageBankSelector selector(4u);
|
||||
|
||||
uint64_t allocationSize = 1024u;
|
||||
auto bankIndex = selector.getLeastOccupiedBank();
|
||||
selector.reserveOnBank(bankIndex, allocationSize);
|
||||
|
||||
EXPECT_EQ(allocationSize, selector.getOccupiedMemorySizeForBank(bankIndex));
|
||||
}
|
||||
|
||||
TEST(localMemoryUsageTest, givenLocalMemoryUsageBankSelectorWhenMemoryIsReleasedThenValueIsCorrectlyAllocated) {
|
||||
LocalMemoryUsageBankSelector selector(1u);
|
||||
|
||||
uint64_t allocationSize = 1024u;
|
||||
auto bankIndex = selector.getLeastOccupiedBank();
|
||||
EXPECT_EQ(0u, bankIndex);
|
||||
selector.reserveOnBank(bankIndex, allocationSize);
|
||||
|
||||
bankIndex = selector.getLeastOccupiedBank();
|
||||
EXPECT_EQ(0u, bankIndex);
|
||||
selector.reserveOnBank(bankIndex, allocationSize);
|
||||
|
||||
selector.freeOnBank(bankIndex, allocationSize);
|
||||
|
||||
EXPECT_EQ(allocationSize, selector.getOccupiedMemorySizeForBank(bankIndex));
|
||||
}
|
||||
|
||||
TEST(localMemoryUsageTest, givenLocalMemoryUsageBankSelectorWhenMemoryAllocatedSeveralTimesItIsStoredOnDifferentBanks) {
|
||||
MockLocalMemoryUsageBankSelector selector(5u);
|
||||
|
||||
uint64_t allocationSize = 1024u;
|
||||
|
||||
auto bankIndex = selector.getLeastOccupiedBank();
|
||||
selector.reserveOnBank(bankIndex, allocationSize);
|
||||
bankIndex = selector.getLeastOccupiedBank();
|
||||
selector.reserveOnBank(bankIndex, allocationSize);
|
||||
bankIndex = selector.getLeastOccupiedBank();
|
||||
selector.reserveOnBank(bankIndex, allocationSize);
|
||||
bankIndex = selector.getLeastOccupiedBank();
|
||||
selector.reserveOnBank(bankIndex, allocationSize);
|
||||
bankIndex = selector.getLeastOccupiedBank();
|
||||
selector.reserveOnBank(bankIndex, allocationSize);
|
||||
|
||||
for (uint32_t i = 0; i < selector.banksCount; i++) {
|
||||
EXPECT_EQ(allocationSize, selector.getOccupiedMemorySizeForBank(i));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(localMemoryUsageTest, givenLocalMemoryUsageBankSelectorWhenIndexIsInvalidThenErrorIsReturned) {
|
||||
LocalMemoryUsageBankSelector selector(3u);
|
||||
EXPECT_THROW(selector.reserveOnBank(8u, 1024u), std::exception);
|
||||
EXPECT_THROW(selector.freeOnBank(8u, 1024u), std::exception);
|
||||
EXPECT_THROW(selector.getOccupiedMemorySizeForBank(8u), std::exception);
|
||||
}
|
||||
|
||||
TEST(localMemoryUsageTest, givenLocalMemoryUsageBankSelectorWhenItsCreatedWithZeroBanksThenErrorIsReturned) {
|
||||
EXPECT_THROW(LocalMemoryUsageBankSelector(0u), std::exception);
|
||||
}
|
||||
} // namespace NEO
|
Reference in New Issue
Block a user