13 UE5 TInlineAllocator介绍

2024-02-24  本文已影响0人  游戏开发程序员

TInlineAllocator

TInlineAllocator的数组

image.png

TFixedAllocator 的数组

内部的2个内存分配器

        // 数量少于NumInlineElements,使用此数组
        TTypeCompatibleBytes<ElementType> InlineData[NumInlineElements];
  
  // 数量超过NumInlineElements, 使用
        typename SecondaryAllocator::template ForElementType<ElementType> SecondaryData;

ResizeAllocation的代码实现

        void ResizeAllocation(SizeType PreviousNumElements, SizeType NumElements,SIZE_T NumBytesPerElement)
        {
            // 检测数量是否满足.
            if(NumElements <= NumInlineElements)
            {
                // SecondaryData被使用的情况
                if(SecondaryData.GetAllocation())
                {
                    // 新数据存入InlineData
                    RelocateConstructItems<ElementType>(
                      (void*)InlineData, 
                      (ElementType*)SecondaryData.GetAllocation(), 
                      PreviousNumElements);

                    // 释放老的元素
                    SecondaryData.ResizeAllocation(0,0,NumBytesPerElement);
                }
            }
            else
            {
                // 数量超出时,SecondaryData未开启使用
                if(!SecondaryData.GetAllocation())
                {
                    // 扩容到NumElements
                    SecondaryData.ResizeAllocation(0,NumElements,NumBytesPerElement);

                    // inline数组元素移动到SecondaryData里
                    RelocateConstructItems<ElementType>((void*)SecondaryData.GetAllocation(), 
                      GetInlineElements(), PreviousNumElements);
                }
                else
                {
                    // SecondaryData已启用,扩容到NumElements
                    SecondaryData.ResizeAllocation(PreviousNumElements, NumElements, NumBytesPerElement);
                }
            }
        }

RelocateConstructItems

    if constexpr (UE::Core::Private::MemoryOps::TCanBitwiseRelocate<DestinationElementType, SourceElementType>::Value)
    {
        FMemory::Memmove(Dest, Source, sizeof(SourceElementType) * Count);
    }
    else
    {
        while (Count)
        {
            typedef SourceElementType RelocateConstructItemsElementTypeTypedef;

            new (Dest) DestinationElementType(*Source);
            ++(DestinationElementType*&)Dest;
            (Source++)->RelocateConstructItemsElementTypeTypedef::~RelocateConstructItemsElementTypeTypedef();
            --Count;
        }
    }

获取分配器函数

        // FContainerAllocatorInterface
        FORCEINLINE ElementType* GetAllocation() const
        {
            return IfAThenAElseB<ElementType>(SecondaryData.GetAllocation(),GetInlineElements());
        }
上一篇 下一篇

猜你喜欢

热点阅读