Open3D (C++ API)  0.17.0
Loading...
Searching...
No Matches
MemoryAllocation.h
Go to the documentation of this file.
1// ----------------------------------------------------------------------------
2// - Open3D: www.open3d.org -
3// ----------------------------------------------------------------------------
4// Copyright (c) 2018-2023 www.open3d.org
5// SPDX-License-Identifier: MIT
6// ----------------------------------------------------------------------------
7
8#pragma once
9
10#include <iostream>
11#include <memory>
12#include <stdexcept>
13#include <utility>
14#include <vector>
15
16namespace open3d {
17namespace core {
18namespace nns {
19
22public:
30 MemoryAllocation(void* ptr, size_t size, size_t alignment = 1)
31 : _ptr(ptr),
32 _size(size),
33 _alignment(alignment),
34 _max_size_ptr((char*)ptr) {
35 // align start and end of memory segment
36 void* aligned_ptr = std::align(_alignment, 1, ptr, size);
37 size_t size_after_align =
38 (((char*)ptr + size) - (char*)aligned_ptr) / _alignment;
39 size_after_align *= _alignment;
40 _free_segments.push_back(
41 std::pair<void*, size_t>(aligned_ptr, size_after_align));
42 }
43
47 template <class T>
48 std::pair<T*, size_t> Alloc(size_t size) {
49 std::pair<void*, size_t> tmp = Alloc(size * sizeof(T));
50 return std::pair<T*, size_t>((T*)tmp.first, tmp.first ? size : 0);
51 }
52
55 std::pair<void*, size_t> Alloc(size_t size) {
56 // round up to alignment
57 if (size % _alignment) size += _alignment - size % _alignment;
58
59 for (size_t i = 0; i < _free_segments.size(); ++i) {
60 void* ptr = std::align(_alignment, size, _free_segments[i].first,
61 _free_segments[i].second);
62 if (ptr) {
63 char* end_ptr = (char*)ptr + size;
64 if (end_ptr > _max_size_ptr) _max_size_ptr = end_ptr;
65
66 _free_segments[i].first = end_ptr;
67 _free_segments[i].second -= size;
68 return std::pair<void*, size_t>(ptr, size);
69 }
70 }
71 return std::pair<void*, size_t>(nullptr, 0);
72 }
73
75 std::pair<void*, size_t> AllocLargestSegment() {
76 size_t size = 0;
77 for (const auto& s : _free_segments)
78 if (s.second > size) size = s.second;
79
80 return Alloc(size);
81 }
82
84 template <class T>
85 void Free(const std::pair<T*, size_t>& segment) {
86 size_t size = sizeof(T) * segment.second;
87 if (size % _alignment) size += _alignment - size % _alignment;
88
89 Free(std::pair<void*, size_t>(segment.first, size));
90 }
91
93 void Free(const std::pair<void*, size_t>& segment) {
94 if (DEBUG) {
95 if ((char*)segment.first < (char*)_ptr ||
96 (char*)segment.first + segment.second > (char*)_ptr + _size)
97 throw std::runtime_error("free(): segment is out of bounds");
98 }
99 {
100 size_t i;
101 for (i = 0; i < _free_segments.size(); ++i) {
102 if ((char*)segment.first < (char*)_free_segments[i].first)
103 break;
104 }
105 _free_segments.insert(_free_segments.begin() + i, segment);
106 }
107
108 // merge adjacent segments
109 auto seg = _free_segments[0];
110 char* end_ptr = (char*)seg.first + seg.second;
111 size_t count = 0;
112 for (size_t i = 1; i < _free_segments.size(); ++i) {
113 const auto& seg_i = _free_segments[i];
114
115 if (end_ptr == (char*)seg_i.first) {
116 // merge with adjacent following segment
117 seg.second += seg_i.second;
118 end_ptr = (char*)seg.first + seg.second;
119 } else {
120 _free_segments[count] = seg;
121 seg = _free_segments[i];
122 end_ptr = (char*)seg.first + seg.second;
123 ++count;
124 }
125 }
126 _free_segments[count] = seg;
127 ++count;
128 _free_segments.resize(count);
129
130 if (DEBUG) {
131 // check if there are overlapping segments
132 for (size_t i = 1; i < _free_segments.size(); ++i) {
133 char* prev_end_ptr = (char*)_free_segments[i - 1].first +
134 _free_segments[i - 1].second;
135 if (prev_end_ptr > (char*)_free_segments[i].first) {
136 throw std::runtime_error(
137 "free(): Overlapping free segments found after "
138 "call to free");
139 }
140 }
141 }
142 }
143
145 size_t MaxUsed() const { return _max_size_ptr - (char*)_ptr; }
146
148 size_t Alignment() const { return _alignment; }
149
151 const std::vector<std::pair<void*, size_t>>& FreeSegments() const {
152 return _free_segments;
153 }
154
156 template <class T>
157 static void PrintSegment(const std::pair<T*, size_t>& s) {
158 std::cerr << "ptr " << (void*)s.first << "\t size " << s.second
159 << "\t end " << (void*)((char*)s.first + s.second) << "\n";
160 }
161
163 void PrintFreeSegments() const {
164 for (const auto& s : _free_segments) PrintSegment(s);
165 }
166
167private:
168 enum internal_config { DEBUG = 0 };
169
171 const void* _ptr;
172
174 const size_t _size;
175
177 const size_t _alignment;
178
180 char* _max_size_ptr;
181
184 std::vector<std::pair<void*, size_t>> _free_segments;
185};
186
187} // namespace nns
188} // namespace core
189} // namespace open3d
A class for managing memory segments within a memory allocation.
Definition MemoryAllocation.h:21
void Free(const std::pair< T *, size_t > &segment)
Frees a previously returned segment.
Definition MemoryAllocation.h:85
static void PrintSegment(const std::pair< T *, size_t > &s)
Prints the segment. Meant for debugging.
Definition MemoryAllocation.h:157
size_t MaxUsed() const
Returns the peak memory usage in bytes.
Definition MemoryAllocation.h:145
MemoryAllocation(void *ptr, size_t size, size_t alignment=1)
Definition MemoryAllocation.h:30
void Free(const std::pair< void *, size_t > &segment)
Frees a previously returned segment.
Definition MemoryAllocation.h:93
std::pair< void *, size_t > Alloc(size_t size)
Definition MemoryAllocation.h:55
std::pair< T *, size_t > Alloc(size_t size)
Definition MemoryAllocation.h:48
void PrintFreeSegments() const
Prints all free segments. Meant for debugging.
Definition MemoryAllocation.h:163
const std::vector< std::pair< void *, size_t > > & FreeSegments() const
Returns the list of free segments.
Definition MemoryAllocation.h:151
size_t Alignment() const
Returns the alignment in bytes.
Definition MemoryAllocation.h:148
std::pair< void *, size_t > AllocLargestSegment()
Returns the largest free segment.
Definition MemoryAllocation.h:75
int size
Definition FilePCD.cpp:40
int count
Definition FilePCD.cpp:42
Definition PinholeCameraIntrinsic.cpp:16