vulkan内存分配类在参考下的尝试实现(草稿

看到参考Vk实现的内存分配器中调用到的几个对齐内存分配函数还蛮有兴趣的,于是自己尝试实现了一下
有一个比较大的问题是不知道std里的_aligned_realloc具体是怎样实现的,自己用先free再malloc的方法乱写了一个,但是发现在简单测试下和调用std中的函数结果是相似的。。。?都能做到不改变指针的值,还请了解这方面的先辈指导一下…

顺便,jetbrain系的某些代码强制格式实在不太好受,,

//
// Created by LCBHSStudent on 2020/1/30.
//

#include <malloc.h>
#include <myusing/myusing.h>

void* aligned_malloc(size_t size, size_t alignment) {
    if(alignment & (alignment - 1)) {
        return nullptr;
    }
    //维护FreeBlock(void)指针占用的内存大小-----用sizeof获取
    int pSize = sizeof (void*);
    // 求得让FreeBlock
    // 内存对齐所需要的内存大小
    unsigned requestedSize = size + alignment - 1 + pSize;
    // 分配的大小
    void* rawMemory = malloc(requestedSize);
    // 实际分配的内存地址(差不多就是指针运算数字形式)
    uintptr_t start = (uintptr_t )rawMemory + pSize;

    // 此处的 & 能高位保留,是由于~导致其他位无关位都变成了1
    void* aligned = (void*)((start + alignment - 1) & ~(alignment-1));

    // 维护一个指向malloc()真正分配的内存的指针
    *(void**) ((uintptr_t) aligned - pSize) = rawMemory;

    return aligned;     //因为做了向上的舍入,所以不需要多余的清理操作

    // 这样分配出的内存,对齐填充位于最前,后面紧跟维护指针,再后就是对象的chain
}

void aligned_free(void* aligned) {
    void* rawMemory = *(void**) ((uintptr_t)aligned - sizeof(void*));
    free(rawMemory);
}

bool isAligned(void* data, unsigned alignment) {
    return ((uintptr_t) data & (alignment - 1)) == 0;
}

void* aligned_realloc(void* data, size_t size, size_t alignment) {
    if(isAligned(data,
                 static_cast<int> (alignment)
    )) {
        aligned_free(data);
        return aligned_malloc(size, alignment);
    } else {
        return nullptr;
    }
}

下面是简单实现的vkAllocator

//
// Created by LCBHSStudent on 2020/1/29.
//

#ifndef VULKANDEMO_VKALLOCATOR_H
#define VULKANDEMO_VKALLOCATOR_H

#include <myusing/myusing.h>
#include <vulkan/vulkan.h>

class VkAllocator {
public:
    inline explicit operator VkAllocationCallbacks () const {
        VkAllocationCallbacks result;
        {
            result.pUserData             = (void*) this;
            result.pfnAllocation         = &Allocation;
            result.pfnReallocation       = &ReAllocation;
            result.pfnFree               = &Free;
            result.pfnInternalAllocation = nullptr;
            result.pfnInternalFree       = nullptr;
        }
        return result;
    }

private:
    static void* VKAPI_CALL Allocation(
            void*                   pUserData,
            size_t                  size,
            size_t                  alignment,
            VkSystemAllocationScope allocationScope);

    static void* VKAPI_CALL ReAllocation(
            void*                   pUserData,
            void*                   pOriginal,
            size_t                  size,
            size_t                  alignment,
            VkSystemAllocationScope allocationScope);

    static void VKAPI_CALL Free(
            void*                   pUserData,
            void*                   pMemory);

    void* Allocation(
            size_t                  size,
            size_t                  alignment,
            VkSystemAllocationScope allocationScope);

    void* ReAllocation(
            void*                   pOriginal,
            size_t                  size,
            size_t                  alignment,
            VkSystemAllocationScope allocationScope);

    void Free(void* pMemory);
};


#endif //VULKANDEMO_VKALLOCATOR_H

//
// Created by LCBHSStudent on 2020/1/29.
//

#include <cassert>
#include "VkAllocator.h"

void* VkAllocator::Allocation(size_t size,
        size_t                  alignment,
        VkSystemAllocationScope allocationScope
        )
{
    auto ret = aligned_malloc(size, alignment);
    assert(ret == nullptr);
    return ret;
}

void* VKAPI_CALL VkAllocator::Allocation(
        void*                   pUserData,
        size_t                  size,
        size_t                  alignment,
        VkSystemAllocationScope allocationScope)
{
    return static_cast<VkAllocator*>(pUserData)->Allocation(size,
            alignment,
            allocationScope);
}

void* VkAllocator::ReAllocation(
        void*                   pOriginal,
        size_t                  size,
        size_t                  alignment,
        VkSystemAllocationScope allocationScope)
{
    return aligned_realloc(pOriginal, size, alignment);
}

void* VKAPI_CALL VkAllocator::ReAllocation(
        void*                   pUserData,
        void*                   pOriginal,
        size_t                  size,
        size_t                  alignment,
        VkSystemAllocationScope allocationScope)
{
    return static_cast<VkAllocator*>(pUserData)->ReAllocation(
            pOriginal, size, alignment, allocationScope);
}

void VkAllocator::Free(void *pMemory) {
    aligned_free(pMemory);
}

void VKAPI_CALL VkAllocator::Free(
        void* pUserData,
        void* pMemory)
{
    return static_cast<VkAllocator*>(pUserData)->Free(pMemory);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章