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:
Pawel Wilma
2019-04-04 10:50:02 +02:00
committed by sys_ocldev
parent f6f5d19704
commit 37bcc99cd2
5 changed files with 162 additions and 0 deletions

View File

@ -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

View 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

View 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

View File

@ -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

View 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