Skip to content
Open

pass #11

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
8 changes: 6 additions & 2 deletions include/core/allocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ namespace infini {
// TODO:可能需要设计一个数据结构来存储free block,以便于管理和合并
// HINT: 可以使用一个 map 来存储 free block,key 为 block 的起始/结尾地址,value 为 block 的大小
// =================================== 作业 ===================================


// 使用 map 存储空闲块,key 为起始地址,value 为块大小
// map 会自动按地址排序,便于查找和合并相邻块
std::map<size_t, size_t> free_blocks;

public:
Allocator(Runtime runtime);

Expand Down Expand Up @@ -56,4 +60,4 @@ namespace infini {
// return: size of the aligned memory block
size_t getAlignedSize(size_t size);
};
}
}
93 changes: 89 additions & 4 deletions src/core/allocator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,103 @@ namespace infini
// =================================== 作业 ===================================
// TODO: 设计一个算法来分配内存,返回起始地址偏移量
// =================================== 作业 ===================================

return 0;

// First Fit 策略:遍历所有空闲块,找到第一个足够大的块
for (auto it = free_blocks.begin(); it != free_blocks.end(); ++it)
{
size_t block_addr = it->first;
size_t block_size = it->second;

// 情况1: 找到足够大的空闲块,直接使用
if (block_size >= size)
{
// 从空闲列表中移除该块
free_blocks.erase(it);

// 如果有剩余空间,将剩余部分重新加入空闲列表
if (block_size > size)
{
free_blocks[block_addr + size] = block_size - size;
}

// 更新已使用内存
this->used += size;

return block_addr;
}
// 情况2: 该块在内存末尾(block_addr + block_size == peak)
// 即使块不够大,也可以扩展使用
else if (block_addr + block_size == this->peak)
{
// 从空闲列表中移除该块
free_blocks.erase(it);

// 计算还需要多少额外空间
size_t extra_needed = size - block_size;

// 扩展 peak
this->peak += extra_needed;

// 更新已使用内存
this->used += size;

return block_addr;
}
}

// 没有找到任何空闲块,在内存末尾分配新空间
size_t block_addr = this->peak;
this->used += size;
this->peak += size;

return block_addr;
}

void Allocator::free(size_t addr, size_t size)
{
IT_ASSERT(this->ptr == nullptr);
size = getAlignedSize(size);

// =================================== 作业 ===================================
// TODO: 设计一个算法来回收内存
// =================================== 作业 ===================================

// 更新已使用内存
this->used -= size;

// 将释放的块加入空闲列表
free_blocks[addr] = size;

// 获取当前释放块的迭代器
auto current = free_blocks.find(addr);

// 尝试与后面的块合并
auto next = std::next(current);
if (next != free_blocks.end())
{
// 如果当前块的结尾恰好是下一个块的开始
if (current->first + current->second == next->first)
{
// 合并:扩展当前块的大小
current->second += next->second;
// 删除下一个块
free_blocks.erase(next);
}
}

// 尝试与前面的块合并
if (current != free_blocks.begin())
{
auto prev = std::prev(current);
// 如果前一个块的结尾恰好是当前块的开始
if (prev->first + prev->second == current->first)
{
// 合并:扩展前一个块的大小
prev->second += current->second;
// 删除当前块
free_blocks.erase(current);
}
}
}

void *Allocator::getPtr()
Expand All @@ -66,4 +151,4 @@ namespace infini
std::cout << "Used memory: " << this->used
<< ", peak memory: " << this->peak << std::endl;
}
}
}
Loading