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
7 changes: 4 additions & 3 deletions include/core/allocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,20 @@ namespace infini {
private:
Runtime runtime;

size_t used;
size_t used; // 当前使用的内存大小(bytes)

size_t peak;
size_t peak; // 历史峰值内存使用大小(bytes)

size_t alignment;

// pointer to the memory actually allocated
void *ptr;
void *ptr; // 预分配时,该指针必须为nullptr,预分配的地址偏移都是相对于ptr的

// =================================== 作业 ===================================
// TODO:可能需要设计一个数据结构来存储free block,以便于管理和合并
// HINT: 可以使用一个 map 来存储 free block,key 为 block 的起始/结尾地址,value 为 block 的大小
// =================================== 作业 ===================================
std::map<size_t, size_t> freeBlocks; // 用于记录预分配的空闲内存块,key为块的起始地址偏移,value为块的大小(bytes)

public:
Allocator(Runtime runtime);
Expand Down
2 changes: 2 additions & 0 deletions include/core/graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include <algorithm>
#include <cstdint>

#include "../operators/transpose.h"
#include "../operators/matmul.h"
namespace infini
{

Expand Down
73 changes: 72 additions & 1 deletion src/core/allocator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,50 @@ namespace infini
// =================================== 作业 ===================================
// TODO: 设计一个算法来分配内存,返回起始地址偏移量
// =================================== 作业 ===================================
// 1. 在 freeBlocks 中查找合适块--首次适配算法
for (auto it = freeBlocks.begin(); it != freeBlocks.end(); ++it) {
if (it->second >= size) { // 找到大小足够的内存块
size_t start_addr = it->first;
size_t block_size = it->second; // 空闲块的原始大小
// 从空闲块列表中移除这个块
freeBlocks.erase(it);
// 检查是否需要分割
if (block_size > size)
{
// 分割:剩余部分作为新的空闲块
size_t remaining_addr = start_addr + size;
size_t remaining_size = block_size - size;
freeBlocks[remaining_addr] = remaining_size;
}
// 如果 block_size == size,就不需要创建新的空闲块
// 更新已使用内存
used += size;
// 更新 peak(检查当前分配是否达到了新的峰值)
size_t end_addr = start_addr + size;
if (end_addr > peak) {
peak = end_addr;
}
return start_addr;
}
}
// 2. freeBlocks 中没有合适块,需要从末尾分配
// 末尾地址就是当前的 peak
auto it = freeBlocks.begin();
size_t start_addr;
if(it->first + it-> second != this->peak) {
start_addr = this->peak; // 从当前 peak 开始分配
size_t end_addr = start_addr + size;
// 更新 peak
this->peak = end_addr;
used += size;
} else { // 末尾拓展
freeBlocks.erase(it);
start_addr = it->first;
this->peak = it->first + size;
used += size;

return 0;
}
return start_addr;
}

void Allocator::free(size_t addr, size_t size)
Expand All @@ -44,6 +86,35 @@ namespace infini
// =================================== 作业 ===================================
// TODO: 设计一个算法来回收内存
// =================================== 作业 ===================================
// 将释放的内存块加入freeBlocks
this->freeBlocks[addr] = size;
this->used -= size;
// 合并相邻的空闲块
auto it = this->freeBlocks.find(addr);
// 检查是否能与前一个块合并
if (it != this->freeBlocks.begin()) {
auto prev = std::prev(it);
if (prev->first + prev->second == it->first) { // first: 起始地址 second: 大小
// 可以合并
prev->second += it->second; // 合并时更新大小
this->freeBlocks.erase(it);
it = prev; // 更新当前迭代器指向合并后的块
} else {
// 不能合并,恢复it指向原始块
it = freeBlocks.find(addr);
}
}

// 检查是否能与后一个块合并
if (it != freeBlocks.end()) {
auto next = std::next(it);
if (next != freeBlocks.end() && it->first + it->second == next->first) {
// 可以合并
it->second += next->second;
freeBlocks.erase(next);
}
}
// 之所以可以这么合并,因为map中key是有序分布的
}

void *Allocator::getPtr()
Expand Down
Loading