Skip to content

Commit

Permalink
Everything now works with fixed size allocators
Browse files Browse the repository at this point in the history
  • Loading branch information
hosseinmoein committed Oct 1, 2023
1 parent 9f63656 commit ef74771
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 48 deletions.
42 changes: 28 additions & 14 deletions include/DataFrame/Utils/FixedSizeAllocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ struct StaticStorage {
using value_type = T;
using size_type = std::size_t;

inline static constexpr size_type max_size = MAX_SIZE;
inline static constexpr size_type max_size = MAX_SIZE * sizeof(value_type);
inline static constexpr bool is_static = true;

StaticStorage() = default;
Expand All @@ -65,7 +65,7 @@ struct StaticStorage {
// Main allocation space
//
alignas(value_type[])
inline static unsigned char buffer_[MAX_SIZE * sizeof(value_type)];
inline static unsigned char buffer_[max_size];
};

// ----------------------------------------------------------------------------
Expand All @@ -76,7 +76,7 @@ struct StackStorage {
using value_type = T;
using size_type = std::size_t;

inline static constexpr size_type max_size = MAX_SIZE;
inline static constexpr size_type max_size = MAX_SIZE * sizeof(value_type);
inline static constexpr bool is_static = false;

StackStorage() = default;
Expand All @@ -90,7 +90,7 @@ struct StackStorage {
// Main allocation space
//
alignas(value_type[])
unsigned char buffer_[MAX_SIZE * sizeof(value_type)];
unsigned char buffer_[max_size];
};

// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -149,7 +149,8 @@ struct BestFitAlgo : public S {

// Like malloc
//
pointer get_space (size_type requested_size) {
[[nodiscard]] pointer
get_space (size_type requested_size) {

for (auto iter = free_blocks_start_.begin();
iter != free_blocks_start_.end();
Expand Down Expand Up @@ -179,7 +180,8 @@ struct BestFitAlgo : public S {

// Like free
//
void put_space (pointer to_be_freed, size_type) {
void
put_space (pointer to_be_freed, size_type) {

auto used_iter = used_blocks_.find({ to_be_freed, 0 });

Expand Down Expand Up @@ -237,7 +239,7 @@ struct BestFitAlgo : public S {
}

// If we could not join with any other adjacent free blocks,
// process it as stand alone
// process it as a stand alone
//
if (! (found_tail || found_head)) {
const pointer end_address =
Expand All @@ -252,19 +254,21 @@ struct BestFitAlgo : public S {
//
used_blocks_.erase(used_iter);
}
else // This is undefined behavior in delete operator
throw std::invalid_argument("BestFitAlgo::put_space()");
// else // This is undefined behavior in delete operator
// throw std::invalid_argument("BestFitAlgo::put_space()");
}

private:

// It is based on size, so it must be multi-set
//
using blk_set = std::multiset<BestFitMemoryBlock>;
using blk_uoset = std::unordered_set<BestFitMemoryBlock, BestFitMemoryBlock>;
using blk_uomap = std::unordered_map<pointer, std::size_t>;

blk_set free_blocks_start_ { }; // Pointres to free block beginnings.
blk_uomap free_blocks_end_ { }; // Pointres to free block ends.
blk_uoset used_blocks_ { }; // Used blocks
blk_uoset used_blocks_ { }; // Set of used blocks
};

// ----------------------------------------------------------------------------
Expand All @@ -282,7 +286,7 @@ struct FirstFitStaticBase : public StaticStorage<T, MAX_SIZE> {

// The bitmap to indicate which slots are in use.
//
alignas(64)
alignas(value_type[])
inline static unsigned char in_use_[MAX_SIZE];

// Pointer to the first free slot.
Expand Down Expand Up @@ -316,7 +320,7 @@ struct FirstFitStackBase : public StackStorage<T, MAX_SIZE> {

// The bitmap to indicate which slots are in use.
//
alignas(64)
alignas(value_type[])
unsigned char in_use_[MAX_SIZE];

// Pointer to the first free slot.
Expand All @@ -342,7 +346,8 @@ struct FirstFitAlgo : public S {

// Like malloc
//
pointer get_space (size_type requested_size) {
[[nodiscard]] pointer
get_space (size_type requested_size) {

// Pointers to the "in use" bitmap.
//
Expand Down Expand Up @@ -381,7 +386,8 @@ struct FirstFitAlgo : public S {

// Like free
//
void put_space (pointer to_be_freed, size_type space_size) {
void
put_space (pointer to_be_freed, size_type space_size) {

// Find the start of the range.
//
Expand Down Expand Up @@ -512,18 +518,26 @@ class FixedSizeAllocator : ALGO<STORAGE<T, MAX_SIZE>> {

// ----------------------------------------------------------------------------

// This is slower than first-fit, but it causes a lot less fragmentations.
//
template<typename T, std::size_t MAX_SIZE>
using StaticBestFitAllocator =
FixedSizeAllocator<T, MAX_SIZE, StaticStorage, BestFitAlgo>;

// This is slower than first-fit, but it causes a lot less fragmentations.
//
template<typename T, std::size_t MAX_SIZE>
using StackBestFitAllocator =
FixedSizeAllocator<T, MAX_SIZE, StackStorage, BestFitAlgo>;

// This is faster than best-fit, but it causes more fragmentations.
//
template<typename T, std::size_t MAX_SIZE>
using StaticFirstFitAllocator =
FixedSizeAllocator<T, MAX_SIZE, FirstFitStaticBase, FirstFitAlgo>;

// This is faster than best-fit, but it causes more fragmentations.
//
template<typename T, std::size_t MAX_SIZE>
using StackFirstFitAllocator =
FixedSizeAllocator<T, MAX_SIZE, FirstFitStackBase, FirstFitAlgo>;
Expand Down
95 changes: 61 additions & 34 deletions test/allocator_tester.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <DataFrame/Utils/AlignedAllocator.h>
#include <DataFrame/Utils/FixedSizeAllocator.h>

#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <iostream>
#include <map>
#include <random>
#include <string>
#include <vector>

Expand Down Expand Up @@ -241,6 +244,35 @@ static void test_first_fit_static_allocator() {
my_map.insert({ i, i * 10 });
for (int i = 0; i < 1000; ++i)
assert((my_map.find(i)->second == i * 10));

FirstFitAlgo<FirstFitStaticBase<int, 10000>> allocator;
std::vector<std::pair<unsigned char *, std::size_t>> ptr_vec;
std::mt19937 gen { 98 };

std::srand(98);
for (std::size_t i = 0; i < 1000; ++i) {
for (std::size_t j = 0; j < 10; ++j) {
const std::size_t size = (std::rand() % 100) * sizeof(int);
const auto ptr = allocator.get_space(size);

ptr_vec.push_back(std::make_pair(ptr, size));
}

std::shuffle(ptr_vec.begin(), ptr_vec.end(), gen);

if ((i % 10) == 0) {
for (std::size_t w = 0; w < (ptr_vec.size() / 3); ++w)
allocator.put_space(ptr_vec[w].first, ptr_vec[w].second);
ptr_vec.erase(ptr_vec.begin(),
ptr_vec.begin() + (ptr_vec.size() / 3));
}
else {
for (std::size_t w = 0; w < (ptr_vec.size() / 2); ++w)
allocator.put_space(ptr_vec[w].first, ptr_vec[w].second);
ptr_vec.erase(ptr_vec.begin(),
ptr_vec.begin() + (ptr_vec.size() / 2));
}
}
}

// -----------------------------------------------------------------------------
Expand Down Expand Up @@ -327,40 +359,6 @@ static void test_first_fit_stack_allocator() {

// -----------------------------------------------------------------------------



































static void test_best_fit_static_allocator() {

std::cout << "\nTesting StaticBestFitAllocator ..." << std::endl;
Expand Down Expand Up @@ -439,6 +437,35 @@ static void test_best_fit_static_allocator() {
my_map.insert({ i, i * 10 });
for (int i = 0; i < 1000; ++i)
assert((my_map.find(i)->second == i * 10));

BestFitAlgo<StaticStorage<int, 10000>> allocator;
std::vector<std::pair<unsigned char *, std::size_t>> ptr_vec;
std::mt19937 gen { 98 };

std::srand(98);
for (std::size_t i = 0; i < 10000; ++i) {
for (std::size_t j = 0; j < 100; ++j) {
const std::size_t size = (std::rand() % 100) * sizeof(int);
const auto ptr = allocator.get_space(size);

ptr_vec.push_back(std::make_pair(ptr, size));
}

std::shuffle(ptr_vec.begin(), ptr_vec.end(), gen);

if ((i % 10) == 0) {
for (std::size_t w = 0; w < (ptr_vec.size() / 3); ++w)
allocator.put_space(ptr_vec[w].first, ptr_vec[w].second);
ptr_vec.erase(ptr_vec.begin(),
ptr_vec.begin() + (ptr_vec.size() / 3));
}
else {
for (std::size_t w = 0; w < (ptr_vec.size() / 2); ++w)
allocator.put_space(ptr_vec[w].first, ptr_vec[w].second);
ptr_vec.erase(ptr_vec.begin(),
ptr_vec.begin() + (ptr_vec.size() / 2));
}
}
}

// -----------------------------------------------------------------------------
Expand Down

0 comments on commit ef74771

Please sign in to comment.