Skip to content

Commit 2146cd0

Browse files
refactor: SortedVectorBasedAllocationTracker
Move code out to base class. This will allow to use the sorted vector class with different values than only SvmData. Signed-off-by: Dominik Dabek <dominik.dabek@intel.com>
1 parent 073000f commit 2146cd0

File tree

8 files changed

+123
-74
lines changed

8 files changed

+123
-74
lines changed

shared/source/memory_manager/unified_memory_manager.cpp

Lines changed: 10 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -42,25 +42,6 @@ void SVMAllocsManager::MapBasedAllocationTracker::remove(const SvmAllocationData
4242
allocations.erase(iter);
4343
}
4444

45-
void SVMAllocsManager::SortedVectorBasedAllocationTracker::insert(const SvmAllocationData &allocationsPair) {
46-
allocations.push_back(std::make_pair(reinterpret_cast<void *>(allocationsPair.gpuAllocations.getDefaultGraphicsAllocation()->getGpuAddress()), std::make_unique<SvmAllocationData>(allocationsPair)));
47-
for (size_t i = allocations.size() - 1; i > 0; --i) {
48-
if (allocations[i].first < allocations[i - 1].first) {
49-
std::iter_swap(allocations.begin() + i, allocations.begin() + i - 1);
50-
} else {
51-
break;
52-
}
53-
}
54-
}
55-
56-
void SVMAllocsManager::SortedVectorBasedAllocationTracker::remove(const SvmAllocationData &allocationsPair) {
57-
auto gpuAddress = reinterpret_cast<void *>(allocationsPair.gpuAllocations.getDefaultGraphicsAllocation()->getGpuAddress());
58-
auto removeIt = std::remove_if(allocations.begin(), allocations.end(), [&gpuAddress](const auto &other) {
59-
return gpuAddress == other.first;
60-
});
61-
allocations.erase(removeIt);
62-
}
63-
6445
void SVMAllocsManager::SvmAllocationCache::insert(size_t size, void *ptr) {
6546
std::lock_guard<std::mutex> lock(this->mtx);
6647
allocations.emplace(std::lower_bound(allocations.begin(), allocations.end(), size), size, ptr);
@@ -132,34 +113,6 @@ SvmAllocationData *SVMAllocsManager::MapBasedAllocationTracker::get(const void *
132113
return nullptr;
133114
}
134115

135-
SvmAllocationData *SVMAllocsManager::SortedVectorBasedAllocationTracker::get(const void *ptr) {
136-
if (allocations.size() == 0) {
137-
return nullptr;
138-
}
139-
if (!ptr) {
140-
return nullptr;
141-
}
142-
143-
int begin = 0;
144-
int end = static_cast<int>(allocations.size() - 1);
145-
while (end >= begin) {
146-
int currentPos = (begin + end) / 2;
147-
const auto &allocation = allocations[currentPos];
148-
if (allocation.first == ptr || (allocation.first < ptr &&
149-
(reinterpret_cast<uintptr_t>(ptr) < (reinterpret_cast<uintptr_t>(allocation.first) + allocation.second->size)))) {
150-
return allocation.second.get();
151-
} else if (ptr < allocation.first) {
152-
end = currentPos - 1;
153-
continue;
154-
} else {
155-
begin = currentPos + 1;
156-
continue;
157-
}
158-
}
159-
160-
return nullptr;
161-
}
162-
163116
void SVMAllocsManager::MapOperationsTracker::insert(SvmMapOperation mapOperation) {
164117
operations.insert(std::make_pair(mapOperation.regionSvmPtr, mapOperation));
165118
}
@@ -286,7 +239,7 @@ void *SVMAllocsManager::createHostUnifiedMemoryAllocation(size_t size,
286239
allocData.setAllocId(this->allocationsCounter++);
287240

288241
std::unique_lock<std::shared_mutex> lock(mtx);
289-
this->svmAllocs.insert(allocData);
242+
this->svmAllocs.insert(usmPtr, allocData);
290243

291244
return usmPtr;
292245
}
@@ -368,9 +321,9 @@ void *SVMAllocsManager::createUnifiedMemoryAllocation(size_t size,
368321
allocData.setAllocId(this->allocationsCounter++);
369322

370323
std::unique_lock<std::shared_mutex> lock(mtx);
371-
this->svmAllocs.insert(allocData);
372324

373325
auto retPtr = reinterpret_cast<void *>(unifiedMemoryAllocation->getGpuAddress());
326+
this->svmAllocs.insert(retPtr, allocData);
374327
UNRECOVERABLE_IF(useExternalHostPtrForCpu && (externalPtr != retPtr));
375328

376329
return retPtr;
@@ -455,8 +408,9 @@ void *SVMAllocsManager::createUnifiedKmdMigratedAllocation(size_t size, const Sv
455408
allocData.setAllocId(this->allocationsCounter++);
456409

457410
std::unique_lock<std::shared_mutex> lock(mtx);
458-
this->svmAllocs.insert(allocData);
459-
return allocationGpu->getUnderlyingBuffer();
411+
auto retPtr = allocationGpu->getUnderlyingBuffer();
412+
this->svmAllocs.insert(retPtr, allocData);
413+
return retPtr;
460414
}
461415

462416
void SVMAllocsManager::setUnifiedAllocationProperties(GraphicsAllocation *allocation, const SvmAllocationProperties &svmProperties) {
@@ -466,12 +420,12 @@ void SVMAllocsManager::setUnifiedAllocationProperties(GraphicsAllocation *alloca
466420

467421
void SVMAllocsManager::insertSVMAlloc(const SvmAllocationData &svmAllocData) {
468422
std::unique_lock<std::shared_mutex> lock(mtx);
469-
svmAllocs.insert(svmAllocData);
423+
svmAllocs.insert(reinterpret_cast<void *>(svmAllocData.gpuAllocations.getDefaultGraphicsAllocation()->getGpuAddress()), svmAllocData);
470424
}
471425

472426
void SVMAllocsManager::removeSVMAlloc(const SvmAllocationData &svmAllocData) {
473427
std::unique_lock<std::shared_mutex> lock(mtx);
474-
svmAllocs.remove(svmAllocData);
428+
svmAllocs.remove(reinterpret_cast<void *>(svmAllocData.gpuAllocations.getDefaultGraphicsAllocation()->getGpuAddress()));
475429
}
476430

477431
bool SVMAllocsManager::freeSVMAlloc(void *ptr, bool blocking) {
@@ -608,7 +562,7 @@ void *SVMAllocsManager::createZeroCopySvmAllocation(size_t size, const SvmAlloca
608562
allocData.size = size;
609563

610564
std::unique_lock<std::shared_mutex> lock(mtx);
611-
this->svmAllocs.insert(allocData);
565+
this->svmAllocs.insert(usmPtr, allocData);
612566
return usmPtr;
613567
}
614568

@@ -676,14 +630,14 @@ void *SVMAllocsManager::createUnifiedAllocationWithDeviceStorage(size_t size, co
676630
allocData.setAllocId(this->allocationsCounter++);
677631

678632
std::unique_lock<std::shared_mutex> lock(mtx);
679-
this->svmAllocs.insert(allocData);
633+
this->svmAllocs.insert(svmPtr, allocData);
680634
return svmPtr;
681635
}
682636

683637
void SVMAllocsManager::freeSVMData(SvmAllocationData *svmData) {
684638
std::unique_lock<std::mutex> lockForIndirect(mtxForIndirectAccess);
685639
std::unique_lock<std::shared_mutex> lock(mtx);
686-
svmAllocs.remove(*svmData);
640+
svmAllocs.remove(reinterpret_cast<void *>(svmData->gpuAllocations.getDefaultGraphicsAllocation()->getGpuAddress()));
687641
}
688642

689643
void SVMAllocsManager::freeZeroCopySvmAllocation(SvmAllocationData *svmData) {

shared/source/memory_manager/unified_memory_manager.h

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "shared/source/memory_manager/multi_graphics_allocation.h"
1212
#include "shared/source/memory_manager/residency_container.h"
1313
#include "shared/source/unified_memory/unified_memory.h"
14+
#include "shared/source/utilities/sorted_vector.h"
1415

1516
#include "memory_properties_flags.h"
1617

@@ -84,18 +85,13 @@ struct SvmMapOperation {
8485

8586
class SVMAllocsManager {
8687
public:
87-
class SortedVectorBasedAllocationTracker {
88-
friend class SVMAllocsManager;
89-
90-
public:
91-
using SvmAllocationContainer = std::vector<std::pair<const void *, std::unique_ptr<SvmAllocationData>>>;
92-
void insert(const SvmAllocationData &);
93-
void remove(const SvmAllocationData &);
94-
SvmAllocationData *get(const void *);
95-
size_t getNumAllocs() const { return allocations.size(); };
96-
97-
SvmAllocationContainer allocations;
88+
struct CompareAcceptOffsetSvmPointers {
89+
bool operator()(const std::unique_ptr<SvmAllocationData> &svmData, const void *ptr, const void *otherPtr) {
90+
return ptr == otherPtr || (otherPtr < ptr &&
91+
(reinterpret_cast<uintptr_t>(ptr) < (reinterpret_cast<uintptr_t>(otherPtr) + svmData->size)));
92+
}
9893
};
94+
using SortedVectorBasedAllocationTracker = BaseSortedPointerWithValueVector<SvmAllocationData, CompareAcceptOffsetSvmPointers>;
9995

10096
class MapBasedAllocationTracker {
10197
friend class SVMAllocsManager;

shared/source/utilities/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright (C) 2019-2022 Intel Corporation
2+
# Copyright (C) 2019-2023 Intel Corporation
33
#
44
# SPDX-License-Identifier: MIT
55
#
@@ -37,6 +37,7 @@ set(NEO_CORE_UTILITIES
3737
${CMAKE_CURRENT_SOURCE_DIR}/software_tags.h
3838
${CMAKE_CURRENT_SOURCE_DIR}/software_tags_manager.cpp
3939
${CMAKE_CURRENT_SOURCE_DIR}/software_tags_manager.h
40+
${CMAKE_CURRENT_SOURCE_DIR}/sorted_vector.h
4041
${CMAKE_CURRENT_SOURCE_DIR}/spinlock.h
4142
${CMAKE_CURRENT_SOURCE_DIR}/stackvec.h
4243
${CMAKE_CURRENT_SOURCE_DIR}/tag_allocator.cpp
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright (C) 2018-2023 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*
6+
*/
7+
8+
#pragma once
9+
#include <algorithm>
10+
#include <memory>
11+
#include <vector>
12+
13+
namespace NEO {
14+
15+
template <typename ValueType, class Compare>
16+
class BaseSortedPointerWithValueVector {
17+
public:
18+
using PointerPair = std::pair<const void *, std::unique_ptr<ValueType>>;
19+
using Container = std::vector<PointerPair>;
20+
21+
BaseSortedPointerWithValueVector() : compareFunctor(Compare()){};
22+
23+
void insert(const void *ptr, const ValueType &value) {
24+
allocations.push_back(std::make_pair(ptr, std::make_unique<ValueType>(value)));
25+
for (size_t i = allocations.size() - 1; i > 0; --i) {
26+
if (allocations[i].first < allocations[i - 1].first) {
27+
std::iter_swap(allocations.begin() + i, allocations.begin() + i - 1);
28+
} else {
29+
break;
30+
}
31+
}
32+
}
33+
34+
void remove(const void *ptr) {
35+
auto removeIt = std::remove_if(allocations.begin(), allocations.end(), [&ptr](const PointerPair &other) {
36+
return ptr == other.first;
37+
});
38+
allocations.erase(removeIt);
39+
}
40+
41+
ValueType *get(const void *ptr) {
42+
if (allocations.size() == 0) {
43+
return nullptr;
44+
}
45+
46+
if (nullptr == ptr) {
47+
return nullptr;
48+
}
49+
50+
int begin = 0;
51+
int end = static_cast<int>(allocations.size() - 1);
52+
while (end >= begin) {
53+
int currentPos = (begin + end) / 2;
54+
const auto &allocation = allocations[currentPos];
55+
56+
if (compareFunctor(allocation.second, ptr, allocation.first)) {
57+
return allocation.second.get();
58+
} else if (ptr < allocation.first) {
59+
end = currentPos - 1;
60+
continue;
61+
} else {
62+
begin = currentPos + 1;
63+
continue;
64+
}
65+
}
66+
67+
return nullptr;
68+
}
69+
70+
size_t getNumAllocs() const { return allocations.size(); }
71+
72+
Container allocations;
73+
Compare compareFunctor;
74+
};
75+
} // namespace NEO

shared/test/unit_test/memory_manager/unified_memory_manager_cache_tests.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ TEST(SortedVectorBasedAllocationTrackerTests, givenSortedVectorBasedAllocationTr
3535
for (uint32_t i = graphicsAllocationsSize - 1; i >= graphicsAllocationsSize / 2; --i) {
3636
data.gpuAllocations.addAllocation(&graphicsAllocations[i]);
3737
data.device = reinterpret_cast<Device *>(graphicsAllocations[i].getGpuAddress());
38-
tracker.insert(data);
38+
tracker.insert(reinterpret_cast<void *>(data.gpuAllocations.getDefaultGraphicsAllocation()->getGpuAddress()), data);
3939
}
4040
for (uint32_t i = 0; i < graphicsAllocationsSize / 2; ++i) {
4141
data.gpuAllocations.addAllocation(&graphicsAllocations[i]);
4242
data.device = reinterpret_cast<Device *>(graphicsAllocations[i].getGpuAddress());
43-
tracker.insert(data);
43+
tracker.insert(reinterpret_cast<void *>(data.gpuAllocations.getDefaultGraphicsAllocation()->getGpuAddress()), data);
4444
}
4545

4646
EXPECT_EQ(tracker.getNumAllocs(), graphicsAllocationsSize);
@@ -56,7 +56,7 @@ TEST(SortedVectorBasedAllocationTrackerTests, givenSortedVectorBasedAllocationTr
5656
MockGraphicsAllocation graphicsAlloc{reinterpret_cast<void *>(0x0), MemoryConstants::pageSize64k};
5757
data.gpuAllocations.addAllocation(&graphicsAlloc);
5858
data.device = reinterpret_cast<Device *>(graphicsAlloc.getGpuAddress());
59-
tracker.insert(data);
59+
tracker.insert(reinterpret_cast<void *>(data.gpuAllocations.getDefaultGraphicsAllocation()->getGpuAddress()), data);
6060

6161
EXPECT_EQ(tracker.getNumAllocs(), graphicsAllocationsSize + 1);
6262
for (uint64_t i = 0; i < graphicsAllocationsSize + 1; ++i) {
@@ -69,7 +69,7 @@ TEST(SortedVectorBasedAllocationTrackerTests, givenSortedVectorBasedAllocationTr
6969
auto data2 = tracker.get(addr2);
7070
EXPECT_EQ(data1->device, addr1);
7171
EXPECT_EQ(data2->device, addr2);
72-
tracker.remove(*data2);
72+
tracker.remove(addr2);
7373
EXPECT_EQ(tracker.getNumAllocs(), graphicsAllocationsSize);
7474
for (uint64_t i = 0; i < graphicsAllocationsSize; ++i) {
7575
if (i < 2) {

shared/test/unit_test/memory_manager/unified_memory_manager_tests.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ TEST_F(SVMLocalMemoryAllocatorTest, whenMultiplePointerWithOffsetPassedThenPrope
223223
allocationData.memoryType = InternalMemoryType::HOST_UNIFIED_MEMORY;
224224
allocationData.size = mockAllocation.getUnderlyingBufferSize();
225225
allocationData.gpuAllocations.addAllocation(&mockAllocation);
226-
svmManager->svmAllocs.insert(allocationData);
226+
svmManager->svmAllocs.insert(unalignedPointer, allocationData);
227227

228228
auto offsetedPointer = ptrOffset(ptr, 2048);
229229
auto usmAllocationData = svmManager->getSVMAlloc(offsetedPointer);
@@ -234,7 +234,7 @@ TEST_F(SVMLocalMemoryAllocatorTest, whenMultiplePointerWithOffsetPassedThenPrope
234234
usmAllocationData = svmManager->getSVMAlloc(unalignedPointer);
235235
EXPECT_NE(nullptr, usmAllocationData);
236236

237-
svmManager->svmAllocs.remove(allocationData);
237+
svmManager->svmAllocs.remove(reinterpret_cast<void *>(allocationData.gpuAllocations.getDefaultGraphicsAllocation()->getGpuAddress()));
238238
svmManager->freeSVMAlloc(ptr, true);
239239
svmManager->freeSVMAlloc(ptr2, true);
240240
}

shared/test/unit_test/utilities/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ target_sources(neo_shared_tests PRIVATE
2121
${CMAKE_CURRENT_SOURCE_DIR}/perf_profiler_tests.cpp
2222
${CMAKE_CURRENT_SOURCE_DIR}/reference_tracked_object_tests.cpp
2323
${CMAKE_CURRENT_SOURCE_DIR}/software_tags_manager_tests.cpp
24+
${CMAKE_CURRENT_SOURCE_DIR}/sorted_vector_tests.cpp
2425
${CMAKE_CURRENT_SOURCE_DIR}/spinlock_tests.cpp
2526
${CMAKE_CURRENT_SOURCE_DIR}/tag_allocator_tests.cpp
2627
${CMAKE_CURRENT_SOURCE_DIR}/timer_util_tests.cpp
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright (C) 2023 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*
6+
*/
7+
8+
#include "shared/source/utilities/sorted_vector.h"
9+
10+
#include "gtest/gtest.h"
11+
12+
struct Comparator {
13+
bool operator()(const std::unique_ptr<size_t> &svmData, const void *ptr, const void *otherPtr) {
14+
return false;
15+
}
16+
};
17+
using TestedSortedVector = NEO::BaseSortedPointerWithValueVector<size_t, Comparator>;
18+
19+
TEST(SortedVectorTest, givenBaseSortedVectorWhenGettingNullptrThenNullptrIsReturned) {
20+
TestedSortedVector testedVector;
21+
EXPECT_EQ(nullptr, testedVector.get(nullptr));
22+
}

0 commit comments

Comments
 (0)