看到參考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);
}