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);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章