Skip to content

Commit

Permalink
Change: Use monotonic memory resource from STL
Browse files Browse the repository at this point in the history
This replaces the custom ChunkMemoryResource with a memory resource from the STL which does effectively exactly the same thing, using a linked list. Therefore, the STL's version is a little better in performance and memory usage.
  • Loading branch information
spnda committed Aug 16, 2024
1 parent bb52c0f commit 19ed25f
Show file tree
Hide file tree
Showing 3 changed files with 3 additions and 66 deletions.
65 changes: 1 addition & 64 deletions include/fastgltf/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,69 +424,6 @@ namespace fastgltf {
return stringified;
}

#if !FASTGLTF_DISABLE_CUSTOM_MEMORY_POOL
class ChunkMemoryResource : public std::pmr::memory_resource {
/**
* The default size of the individual blocks we allocate.
*/
constexpr static std::size_t blockSize = 2048;

struct Block {
std::unique_ptr<std::byte[]> data;
std::size_t size;

std::byte* dataPointer;
};
SmallVector<Block, 4> blocks;
std::size_t blockIdx = 0;

public:
explicit ChunkMemoryResource() {
allocateNewBlock();
}

void allocateNewBlock() {
auto& block = blocks.emplace_back();
block.data = std::unique_ptr<std::byte[]>(new std::byte[blockSize]);
block.dataPointer = block.data.get();
block.size = blockSize;
}

[[nodiscard]] void* do_allocate(std::size_t bytes, std::size_t alignment) override {
auto& block = blocks[blockIdx];
auto availableSize = static_cast<std::size_t>(block.dataPointer - block.data.get());
if ((availableSize + bytes) > block.size) {
// The block can't fit the new allocation. We'll just create a new block and use that.
allocateNewBlock();
++blockIdx;
return do_allocate(bytes, alignment);
}

void* alloc = block.dataPointer;
std::size_t space = availableSize;
if (std::align(alignment, availableSize, alloc, space) == nullptr) {
// Not enough space after alignment
allocateNewBlock();
++blockIdx;
return do_allocate(bytes, alignment);
}

// Get the number of bytes used for padding, and calculate the new offset using that
block.dataPointer = block.dataPointer + (availableSize - space) + bytes;
return alloc;
}

void do_deallocate([[maybe_unused]] void* p, [[maybe_unused]] std::size_t bytes, [[maybe_unused]] std::size_t alignment) override {
// We currently do nothing, as we don't keep track of what portions of the blocks are still used.
// Therefore, we keep all blocks alive until the destruction of this resource (parser).
}

[[nodiscard]] bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override {
return this == std::addressof(other);
}
};
#endif

/**
* A type that stores an error together with an expected value.
* To use this type, first call error() to inspect if any errors have occurred.
Expand Down Expand Up @@ -845,7 +782,7 @@ namespace fastgltf {
ParserInternalConfig config = {};
DataSource glbBuffer;
#if !FASTGLTF_DISABLE_CUSTOM_MEMORY_POOL
std::shared_ptr<ChunkMemoryResource> resourceAllocator;
std::shared_ptr<std::pmr::monotonic_buffer_resource> resourceAllocator;
#endif
std::filesystem::path directory;
Options options = Options::None;
Expand Down
2 changes: 1 addition & 1 deletion include/fastgltf/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2115,7 +2115,7 @@ namespace fastgltf {
#if !FASTGLTF_DISABLE_CUSTOM_MEMORY_POOL
// This has to be first in this struct so that it gets destroyed last, leaving all allocations
// alive until the end.
std::shared_ptr<ChunkMemoryResource> memoryResource;
std::shared_ptr<std::pmr::monotonic_buffer_resource> memoryResource;
#endif

public:
Expand Down
2 changes: 1 addition & 1 deletion src/fastgltf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1420,7 +1420,7 @@ fg::Expected<fg::Asset> fg::Parser::parse(simdjson::dom::object root, Category c

#if !FASTGLTF_DISABLE_CUSTOM_MEMORY_POOL
// Create a new chunk memory resource for each asset we parse.
asset.memoryResource = resourceAllocator = std::make_shared<ChunkMemoryResource>();
asset.memoryResource = resourceAllocator = std::make_shared<std::pmr::monotonic_buffer_resource>();
#endif

if (!hasBit(options, Options::DontRequireValidAssetMember)) {
Expand Down

0 comments on commit 19ed25f

Please sign in to comment.