Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Do not change these options in this file. Use cmake.config, cmake -DOPTION=VALUE, or ccmake to specify them.
option(BUILD_TEST "Build tests" OFF)

cmake_minimum_required(VERSION 3.17)
cmake_minimum_required(VERSION 3.15)

include(CMakeDependentOption)
project(InfiniTensor C CXX)
Expand Down
5 changes: 2 additions & 3 deletions include/core/allocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
#endif
#include <cstddef>
#include <map>
#include <unordered_set>

namespace infini {
class Allocator
{
Expand All @@ -27,7 +25,8 @@ namespace infini {
// TODO:可能需要设计一个数据结构来存储free block,以便于管理和合并
// HINT: 可以使用一个 map 来存储 free block,key 为 block 的起始/结尾地址,value 为 block 的大小
// =================================== 作业 ===================================

// key: free block start offset, value: free block size
std::map<size_t, size_t> freeBlocks;
public:
Allocator(Runtime runtime);

Expand Down
99 changes: 96 additions & 3 deletions src/core/allocator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,51 @@ namespace infini
size = this->getAlignedSize(size);

// =================================== 作业 ===================================
// TODO: 设计一个算法来分配内存,返回起始地址偏移量
// 采用 free-list + 合并 的方式进行模拟分配:
// 1) 优先从空闲块中找可用块(best-fit,减少碎片)
// 2) 若没有合适空闲块,则从末尾 bump 分配
// 返回分配块的起始 offset
// =================================== 作业 ===================================
size_t bestStart = 0;
size_t bestSize = 0;
bool found = false;
for (const auto &kv : freeBlocks)
{
const size_t start = kv.first;
const size_t blkSize = kv.second;
if (blkSize < size)
continue;
if (!found || blkSize < bestSize)
{
bestStart = start;
bestSize = blkSize;
found = true;
if (blkSize == size)
break;
}
}

if (found)
{
auto it = freeBlocks.find(bestStart);
IT_ASSERT(it != freeBlocks.end());
if (bestSize == size)
{
freeBlocks.erase(it);
}
else
{
freeBlocks.erase(it);
freeBlocks.emplace(bestStart + size, bestSize - size);
}
return bestStart;
}

return 0;
const size_t offset = this->used;
this->used += size;
if (this->used > this->peak)
this->peak = this->used;
return offset;
}

void Allocator::free(size_t addr, size_t size)
Expand All @@ -42,8 +83,60 @@ namespace infini
size = getAlignedSize(size);

// =================================== 作业 ===================================
// TODO: 设计一个算法来回收内存
// 回收逻辑:
// 1) 若释放的是末尾块,直接回退 used,并持续吞并末尾相邻的空闲块
// 2) 否则插入 freeBlocks,并与前后相邻空闲块合并
// =================================== 作业 ===================================
IT_ASSERT(size > 0);
IT_ASSERT(addr + size <= this->used);

// Case 1: free at the end -> shrink
if (addr + size == this->used)
{
this->used = addr;
// continue shrinking if there are free blocks at the new end
while (true)
{
if (freeBlocks.empty())
break;
auto it = freeBlocks.upper_bound(this->used);
if (it == freeBlocks.begin())
break;
--it;
const size_t start = it->first;
const size_t blkSize = it->second;
if (start + blkSize != this->used)
break;
this->used = start;
freeBlocks.erase(it);
}
return;
}

// Case 2: insert + coalesce
size_t newStart = addr;
size_t newSize = size;

auto next = freeBlocks.lower_bound(newStart);
if (next != freeBlocks.begin())
{
auto prev = std::prev(next);
if (prev->first + prev->second == newStart)
{
newStart = prev->first;
newSize += prev->second;
freeBlocks.erase(prev);
}
}

next = freeBlocks.lower_bound(newStart);
if (next != freeBlocks.end() && newStart + newSize == next->first)
{
newSize += next->second;
freeBlocks.erase(next);
}

freeBlocks.emplace(newStart, newSize);
}

void *Allocator::getPtr()
Expand Down
Loading