GPU虚拟化实现(五)

章节回顾

在上一章,简单介绍了项目拦截cuda函数的流程,其本质上与拦截nvml函数的流程是一致的,都是首先将源函数的地址存储在列表的指针中,当拦截到函数时跳转到自定义实现的函数,需要特殊处理就特殊处理,如不需要转到源函数去处理。在这一章,将会介绍这个项目的allocator模块。

初步介绍

项目中的allocator模块时自定义实现的 CUDA 设备显存分配器,主要负责实际的显存分配、释放、追踪和 OOM 检查。

详细介绍

核心数据结构

分配器的运作依赖于几个关键的数据结构(定义在 allocator.h 中):

  1. allocated_device_memory_struct
struct allocated_device_memory_struct{
   
    CUdeviceptr address;                       // 设备显存的指针
    size_t length;                             // 分配的大小
    CUcontext ctx;                             // 关联的 CUDA 上下文
    CUmemGenericAllocationHandle *allocHandle; // 分配句柄
};
typedef struct allocated_device_memory_struct allocated_device_memory;

这个结构体用来存储单块已分配的 CUDA 设备显存的关键信息。
2. allocated_list_structallocated_list_entry_struct

struct allocated_list_entry_struct{
   
    allocated_device_memory *entry;;
    struct allocated_list_entry_struct *next,*prev;
};
typedef struct allocated_list_entry_struct allocated_list_entry;

struct allocated_list_struct{
   
    allocated_list_entry *head;
    allocated_list_entry *tail;
    size_t length;
};
typedef struct allocated_list_struct allocated_list;

allocated_list_entry定义了双向链表中的一个节点。每个节点代表着一块被追踪的设备显存。
allocated_list是一个双向链表,用于存储分配的显存记录。
3. region_struct, region_list_structregion_list_entry_struct(在 allocator.c 这个文件的代码逻辑里,并没有直接使用 region 相关的结构和逻辑)

struct region_struct{
   
    size_t start;
    size_t freemark;
    size_t freed_map;
    size_t length;
    CUcontext ctx;
    allocated_list *region_allocs;
    char *bitmap;
    CUmemGenericAllocationHandle *allocHandle;
};
typedef struct region_struct region;

struct region_list_entry_struct{
   
    region *entry;
    struct region_list_entry_struct *next,*prev;
};
typedef struct region_list_entry_struct region_list_entry;

struct region_list_struct{
   
    region_list_entry   *head;
    region_list_entry   *tail;
    size_t length;
};
typedef struct region_list_struct region_list;

大白话解释:
想象 GPU 显存是一整块大蛋糕,为了方便管理,我们先把它分成几块“大蛋糕”(region),每一块大蛋糕都有自己的档案,记录大小、位置、还有哪些部分被切走了。大蛋糕的档案都串在一起(region_list_entry),放在一个总账本里(region_list),让你随时能找到所有大蛋糕的信息。

每块大蛋糕还能再切成很多“小蛋糕”,分给不同的任务用。每块小蛋糕的信息(位置、大小、谁在用)也记录在小纸条上(allocated_device_memory),这些小纸条串成一串(allocated_list_entry),放在一个小账本里(allocated_list)。而每个大蛋糕的档案里,都有一个指向自己小账本的指针(region_allocs),让你知道从这块大蛋糕切出去的小蛋糕有哪些。

核心功能和运作机制

初始化

// allocator.c
void allocator_init(){
   
    LOG_DEBUG("Allocator_init\n");
    
    device_overallocated = malloc(sizeof(allocated_list));
    LIST_INIT(device_overallocated);
    
    pthread_mutex_init(&mutex,NULL);
}
// allocator.h
#define LIST_INIT(list) {
        \
    list->head=NULL;         \
    list->tail=NULL;         \
    list
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想看一次满天星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值