diff --git a/Lib/CMakeLists.txt b/Lib/CMakeLists.txt index 2857b1ac907c707209c3dcb82d0da5553043efa0..cac917337791bc7640fe2d6005b344c720ab86b4 100644 --- a/Lib/CMakeLists.txt +++ b/Lib/CMakeLists.txt @@ -36,10 +36,14 @@ if(INCLUDE_CUDA) endif(INCLUDE_CUDA) set(SOURCES + buffer.cpp + mf-utils.cpp memory-faucet.cpp ) set(HEADER + buffer.h + mf-utils.h memory-faucet.h ) diff --git a/Lib/buffer.cpp b/Lib/buffer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..919d511989f082d546d3f7d683dae0c5a290a0b7 --- /dev/null +++ b/Lib/buffer.cpp @@ -0,0 +1,188 @@ +#include "buffer.h" +#include "MemoryProcessing.h" +#ifdef INCLUDE_CUDA +#include "MemoryProcessing.cuh" +#endif +// void dyn_dispatch_buffer::reallocate(buffer_base* obj, const size_t required_size) +// { +// obj->reallocate(required_size); +// } + +// void dyn_dispatch_buffer::deallocate(buffer_base* obj) +// { +// obj->deallocate(); +// } + +buffer_base::buffer_base() +{ + ptr = nullptr; + allocated_size = 0; + scalar_size = 0; + is_free = true; + id = -1; + // ! resolve + mem = MemType::CPU; +} + +void buffer_base::reallocate(const size_t required_size) +{ + if(mem == MemType::CPU) + memproc::realloc<MemType::CPU>((void *&)ptr, allocated_size, required_size); +#ifdef INCLUDE_CUDA + else if(mem == MemType::GPU) + memproc::realloc<MemType::GPU>((void *&)ptr, allocated_size, required_size); +#endif +} + +void buffer_base::deallocate() +{ + if(mem == MemType::CPU) + memproc::dealloc<MemType::CPU>((void *&)ptr, allocated_size); +#ifdef INCLUDE_CUDA + else if(mem == MemType::GPU) + memproc::dealloc<MemType::GPU>((void *&)ptr, allocated_size); +#endif +} + +buffer_base::~buffer_base() +{ + deallocate(); + ptr = nullptr; + scalar_size = 0; + is_free = true; + id = -1; +} + + +buffer_base::buffer_base(const buffer_base& other) +{ + mem = other.mem; + allocated_size = 0; + reallocate(other.get_size()); + is_free = other.get_status(); + id = other.get_id(); +} + +buffer_base::buffer_base(buffer_base&& other) +{ + mem = other.mem; + ptr = other.ptr; + allocated_size = other.allocated_size; + scalar_size = other.scalar_size; + is_free = other.is_free; + id = other.id; + + other.ptr = nullptr; + other.allocated_size = 0; + other.scalar_size = 0; + other.is_free = false; + other.id = -1; +} + +buffer_base& buffer_base::operator=(const buffer_base& other) +{ + if (this == &other) + return *this; + + mem = other.mem; + reallocate(other.get_size()); + is_free = other.get_status(); + id = other.get_id(); + + return *this; +} + +buffer_base& buffer_base::operator=(buffer_base&& other) +{ + if (this != &other) + { + mem = other.mem; + deallocate(); + ptr = other.ptr; + allocated_size = other.allocated_size; + scalar_size = other.scalar_size; + is_free = other.is_free; + id = other.id; + + other.ptr = nullptr; + other.allocated_size = 0; + other.scalar_size = 0; + other.is_free = false; + other.id = -1; + } + + return *this; +} + + +bool buffer_base::is_available() const +{ + return is_free; +} + +buffer_base::buffer_base(const size_t required_size, const MemType mem_in) +{ + mem = mem_in; + ptr = nullptr; + allocated_size = 0; + reallocate(required_size); + scalar_size = 0; + is_free = false; +} + +void* buffer_base::get_ptr() +{ + return ptr; +} + +bool buffer_base::get_status() const +{ + return is_free; +} + +size_t buffer_base::get_size() const +{ + return allocated_size; +} + +int buffer_base::get_id() const +{ + return id; +} + +void buffer_base::set_allocated_size(const size_t required_size) +{ + allocated_size = required_size; +} + +void buffer_base::set_null_pointer() +{ + ptr = nullptr; +} + +void buffer_base::set_status(const bool status) +{ + is_free = status; +} + +void buffer_base::set_id(const int idx) +{ + id = idx; +} + +// template< MemType mem > +// void buffer<mem>::reallocate(const size_t required_size) +// { +// memproc::realloc<mem>((void *&)ptr, allocated_size, required_size); +// } + +// template< MemType mem > +// void buffer<mem>::deallocate() +// { +// memproc::deallocate<mem>((void *&)ptr, allocated_size); +// } + +// template class buffer<MemType::CPU>; +// #ifdef INCLUDE_CUDA +// template class buffer<MemType::GPU>; +// #endif \ No newline at end of file diff --git a/Lib/buffer.h b/Lib/buffer.h new file mode 100644 index 0000000000000000000000000000000000000000..9a5addb9fe28bd128bdb341ff4cb275703947495 --- /dev/null +++ b/Lib/buffer.h @@ -0,0 +1,64 @@ +#pragma once +#include "TemplateParameters.h" +#include <cstdlib> + +class buffer_base +{ +public: + void *ptr; + size_t allocated_size; + size_t scalar_size; + bool is_free; + int id; + MemType mem; + + buffer_base(); // Done + buffer_base(const size_t required_size, const MemType mem); // Done + buffer_base(const buffer_base& other); // Done + buffer_base(buffer_base&& other); // Done + ~buffer_base(); // Done + + bool is_available() const; // Done + void* get_ptr(); // Done + bool get_status() const; // Done + size_t get_size() const; // Done + int get_id() const; // Done + + void set_allocated_size(const size_t required_size); // Done + void set_status(const bool status); // Done + void set_id(const int id); // Done + void set_null_pointer(); // Done + + buffer_base& operator=(const buffer_base& other); // Done + buffer_base& operator=(buffer_base&& other); // Done + + void reallocate(const size_t required_size); + void deallocate(); +}; + +// namespace dyn_dispatch_buffer +// { +// void reallocate(buffer_base* obj, const size_t required_size); +// void deallocate(buffer_base* obj); +// }; + +// template< MemType mem > +// class buffer: public buffer_base +// { +// private: +// using buffer_base::ptr; +// using buffer_base::allocated_size; +// using buffer_base::scalar_size; +// using buffer_base::is_free; +// using buffer_base::id; + +// public: +// buffer(const buffer<mem>& other) : buffer_base(other) {} +// buffer(buffer<mem>&& other) : buffer_base(other) {} +// buffer() : buffer_base() {} +// ~buffer(){}; +// buffer(const size_t required_size) : buffer_base(required_size) {} + +// void reallocate(const size_t required_size) override; +// void deallocate() override; +// }; \ No newline at end of file diff --git a/Lib/memory-faucet.cpp b/Lib/memory-faucet.cpp index 9f3d6c7e02d0c25f0e45270e6a3cc58d7ba11ef8..911fc8e0f361bc83108bfcae166bc94c487110f5 100644 --- a/Lib/memory-faucet.cpp +++ b/Lib/memory-faucet.cpp @@ -1,426 +1,76 @@ #include "memory-faucet.h" +#include "mf-utils.h" + #include "MemoryProcessing.h" #ifdef INCLUDE_CUDA #include "MemoryProcessing.cuh" #endif -template< MemType mem > -buffer<mem>::buffer() -{ - ptr = nullptr; - allocated_size = 0; - scalar_size = 0; - is_free = true; - id = -1; -} - -template< MemType mem > -buffer<mem>::~buffer() -{ - memproc::dealloc<mem>((void *&)ptr, allocated_size); -} - -template< MemType mem > -bool buffer<mem>::is_available() const -{ - return is_free; -} - -template< MemType mem > -void buffer<mem>::reallocate(const size_t required_size) -{ - memproc::realloc<mem>((void *&)ptr, allocated_size, required_size); -} - -template< MemType mem > -buffer<mem>::buffer(const size_t required_size) -{ - ptr = nullptr; - allocated_size = 0; - reallocate(required_size); - scalar_size = 0; - is_free = false; -} - -template< MemType mem > -bool free_size_comparator(const buffer<mem>& obj, const size_t required_size) -{ - if(obj.get_status() == false) - return false; - - return obj.get_size() <= required_size; -} - -template bool free_size_comparator(const buffer<MemType::CPU>& obj, const size_t required_size); -#ifdef INCLUDE_CUDA -template bool free_size_comparator(const buffer<MemType::GPU>& obj, const size_t required_size); -#endif - -template< MemType mem > -bool size_comparator(const size_t required_size, const buffer<mem>& obj) -{ - return required_size < obj.get_size(); -} - -template bool size_comparator(const size_t required_size, const buffer<MemType::CPU>& obj); -#ifdef INCLUDE_CUDA -template bool size_comparator(const size_t required_size, const buffer<MemType::GPU>& obj); -#endif - -template< MemType mem > -void* buffer<mem>::get_ptr() -{ - return ptr; -} - -template< MemType mem > -bool buffer<mem>::get_status() const -{ - return is_free; -} - -template< MemType mem > -size_t buffer<mem>::get_size() const -{ - return allocated_size; -} - -template< MemType mem > -int buffer<mem>::get_id() const -{ - return id; -} - -template< MemType mem > -void buffer<mem>::set_allocated_size(const size_t required_size) -{ - allocated_size = required_size; -} - -template< MemType mem > -void buffer<mem>::set_null_pointer() -{ - ptr = nullptr; -} - -template< MemType mem > -buffer<mem>::buffer(const buffer<mem>& other) -{ - allocated_size = 0; - reallocate(other.get_size()); - is_free = other.get_status(); - id = other.get_id(); -} - -template< MemType mem > -buffer<mem>::buffer(buffer<mem>&& other) -{ - ptr = other.ptr; - allocated_size = other.allocated_size; - scalar_size = other.scalar_size; - is_free = other.is_free; - id = other.id; - - other.ptr = nullptr; - other.allocated_size = 0; - other.scalar_size = 0; - other.is_free = false; - other.id = -1; -} - -template< MemType mem > -buffer<mem>& buffer<mem>::operator=(const buffer<mem>& other) -{ - if (this == &other) - return *this; - - reallocate(other.get_size()); - is_free = other.get_status(); - id = other.get_id(); - - return *this; -} - -template< MemType mem > -buffer<mem>& buffer<mem>::operator=(buffer<mem>&& other) -{ - if (this != &other) - { - memproc::dealloc<mem>((void *&)ptr, allocated_size); - ptr = other.ptr; - allocated_size = other.allocated_size; - scalar_size = other.scalar_size; - is_free = other.is_free; - id = other.id; - - other.ptr = nullptr; - other.allocated_size = 0; - other.scalar_size = 0; - other.is_free = false; - other.id = -1; - } - - return *this; -} - -template< MemType mem > -void buffer<mem>::set_status(const bool status) -{ - is_free = status; -} - -template< MemType mem > -void buffer<mem>::set_id(const int idx) -{ - id = idx; -} - -template class buffer<MemType::CPU>; -#ifdef INCLUDE_CUDA -template class buffer<MemType::GPU>; -#endif - -memory_pipe_base::memory_pipe_base() -{ -#ifdef INCLUDE_CUDA - gpu_buff = std::vector<buffer<MemType::GPU> > (); -#endif - cpu_buff = std::vector<buffer<MemType::CPU> > (); -} - -memory_pipe_base::~memory_pipe_base() -{ -#ifdef INCLUDE_CUDA - gpu_buff.clear(); -#endif - cpu_buff.clear(); -} - -template< > -std::vector<buffer<MemType::CPU> >& memory_pipe_base::get_memtyped_vector() +template< MemType mem, buf_choose_policy choose_type > +memory_pipe<mem, choose_type>::memory_pipe() { - return cpu_buff; + buff_vec = std::vector<buffer_base > (); } -#ifdef INCLUDE_CUDA -template<> -std::vector<buffer<MemType::GPU> >& memory_pipe_base::get_memtyped_vector() +template< MemType mem, buf_choose_policy choose_type > +memory_pipe<mem, choose_type>::~memory_pipe() { - return gpu_buff; + buff_vec.clear(); } -#endif -template< MemType mem > -void memory_pipe_base::set_available(const int id) +template< MemType mem, buf_choose_policy choose_type > +void memory_pipe<mem, choose_type>::set_available(const int id) { - get_memtyped_vector<mem>()[id].set_status(true); + buff_vec[id].set_status(true); } -template void memory_pipe_base::set_available<MemType::CPU>(const int id); -#ifdef INCLUDE_CUDA -template void memory_pipe_base::set_available<MemType::GPU>(const int id); -#endif - -template< MemType mem > -typename std::vector<buffer<mem>>::iterator get_lower_bound(typename std::vector<buffer<mem>>::iterator first, - typename std::vector<buffer<mem>>::iterator last, const size_t value, std::function<bool (const buffer<mem>&, const size_t) >& comp) +template< MemType mem, buf_choose_policy choose_type > +std::vector<buffer_base >& memory_pipe<mem, choose_type>::get_buff_vec() { - typename std::vector<buffer<mem>>::iterator it; - typename std::iterator_traits<typename std::vector<buffer<mem>>::iterator>::difference_type count, step; - count = std::distance(first, last); - - while (count > 0) - { - it = first; - step = count / 2; - it = std::next(it, step); - - if (comp(*it, value)) - { - first = ++it; - count -= step + 1; - } - else - count = step; - } - - return first; + return buff_vec; } -template typename std::vector<buffer<MemType::CPU>>::iterator get_lower_bound<MemType::CPU >(typename std::vector<buffer<MemType::CPU>>::iterator first, - typename std::vector<buffer<MemType::CPU>>::iterator last, const size_t value, std::function<bool (const buffer<MemType::CPU>&, const size_t)>& ); -#ifdef INCLUDE_CUDA -template typename std::vector<buffer<MemType::GPU>>::iterator get_lower_bound<MemType::GPU >(typename std::vector<buffer<MemType::GPU>>::iterator first, - typename std::vector<buffer<MemType::GPU>>::iterator last, const size_t value, std::function<bool (const buffer<MemType::GPU>&, const size_t)>& ); -#endif - -template< MemType mem > -typename std::vector<buffer<mem>>::iterator get_upper_bound(typename std::vector<buffer<mem>>::iterator first, - typename std::vector<buffer<mem>>::iterator last, const size_t value, std::function<bool (const size_t, const buffer<mem>&) >& comp) -{ - typename std::vector<buffer<mem>>::iterator it; - typename std::iterator_traits<typename std::vector<buffer<mem>>::iterator>::difference_type count, step; - count = std::distance(first, last); - - while (count > 0) - { - it = first; - step = count / 2; - it = std::next(it, step); - - if (!comp(value, *it)) - { - first = ++it; - count -= step + 1; - } - else - count = step; - } - - return first; -} +template class memory_pipe<MemType::CPU, buf_choose_policy::naive>; +template class memory_pipe<MemType::CPU, buf_choose_policy::sorted_vec>; +template class memory_pipe<MemType::CPU, buf_choose_policy::find_best_unsorted>; -template typename std::vector<buffer<MemType::CPU>>::iterator get_upper_bound<MemType::CPU >(typename std::vector<buffer<MemType::CPU>>::iterator first, - typename std::vector<buffer<MemType::CPU>>::iterator last, const size_t value, std::function<bool (const size_t, const buffer<MemType::CPU>&)>& ); #ifdef INCLUDE_CUDA -template typename std::vector<buffer<MemType::GPU>>::iterator get_upper_bound<MemType::GPU >(typename std::vector<buffer<MemType::GPU>>::iterator first, - typename std::vector<buffer<MemType::GPU>>::iterator last, const size_t value, std::function<bool (const size_t, const buffer<MemType::GPU>&)>& ); +template class memory_pipe<MemType::GPU, buf_choose_policy::naive>; +template class memory_pipe<MemType::GPU, buf_choose_policy::sorted_vec>; +template class memory_pipe<MemType::GPU, buf_choose_policy::find_best_unsorted>; #endif -template<buf_choose_policy choose_type> -template< MemType mem > -int memory_pipe<choose_type>::get_buffer(const size_t required_size, void ** ptr) -{ - std::vector<buffer<mem> >& buff_vec = get_memtyped_vector<mem>(); - const int allocated_buffer_n = buff_vec.size(); - for (int i = 0; i < allocated_buffer_n; i++) - { - const bool is_free = buff_vec[i].get_status(); - const int avail_size = buff_vec[i].get_size(); - - if(is_free == true && required_size <= avail_size) - { - (*ptr) = buff_vec[i].get_ptr(); - buff_vec[i].set_status(false); - return i; - } - } - buff_vec.push_back(buffer<mem>(required_size)); - - (*ptr) = buff_vec.back().get_ptr(); - int id = buff_vec.size() - 1; - - buff_vec.back().set_status(false); - buff_vec.back().set_id(id); - - return id; -} - -template int memory_pipe<buf_choose_policy::naive>::get_buffer<MemType::CPU>(const size_t required_size, void ** ptr); -#ifdef INCLUDE_CUDA -template int memory_pipe<buf_choose_policy::naive>::get_buffer<MemType::GPU>(const size_t required_size, void ** ptr); -#endif - -// template< > -template< MemType mem > -int memory_pipe<buf_choose_policy::sorted_vec>::get_buffer(const size_t required_size, void ** ptr) +template< MemType mem, buf_choose_policy choose_type > +memory_pipe<mem, choose_type>& memory_faucet::get_faucet() { - std::vector<buffer<mem> >& buff_vec = get_memtyped_vector<mem>(); - const int allocated_buffer_n = buff_vec.size(); - for (int i = 0; i < allocated_buffer_n; i++) - { - const bool is_free = buff_vec[i].get_status(); - const int avail_size = buff_vec[i].get_size(); - - if(is_free == true && required_size <= avail_size) - { - (*ptr) = buff_vec[i].get_ptr(); - buff_vec[i].set_status(false); - return i; - } - } - - typename std::vector<buffer<mem>>::iterator buf_it; - std::function<bool (const size_t, const buffer<mem>&) > comparator = size_comparator<mem>; - buf_it = get_upper_bound<mem> (buff_vec.begin(), buff_vec.end(), required_size, comparator); - buf_it = buff_vec.insert(buf_it, buffer<mem>(required_size)); - (*ptr) = buf_it->get_ptr(); - int id = std::distance(buff_vec.begin(), buf_it); - buff_vec.back().set_id(id); - return id; + static memory_pipe<mem, choose_type> mem_pipe = memory_pipe<mem, choose_type>(); + return mem_pipe; } -template int memory_pipe<buf_choose_policy::sorted_vec>::get_buffer<MemType::CPU>(const size_t required_size, void ** ptr); -#ifdef INCLUDE_CUDA -template int memory_pipe<buf_choose_policy::sorted_vec>::get_buffer<MemType::GPU>(const size_t required_size, void ** ptr); -#endif - -// template< > -template< MemType mem > -int memory_pipe<buf_choose_policy::find_best_unsorted>::get_buffer(const size_t required_size, void ** ptr) -{ - std::vector<buffer<mem> >& buff_vec = get_memtyped_vector<mem>(); - typename std::vector<buffer<mem>>::iterator available_buf_it; - std::function<bool (const buffer<mem>&, const size_t) > comparator = free_size_comparator<mem>; - available_buf_it = get_lower_bound<mem> (buff_vec.begin(), buff_vec.end(), required_size, comparator); - if(available_buf_it != buff_vec.end()) - { - (*ptr) = available_buf_it->get_ptr(); - int id = std::distance(buff_vec.begin(), available_buf_it); - buff_vec[id].set_status(false); - return id; - } - else - { - buff_vec.push_back(buffer<mem>(required_size)); - (*ptr) = buff_vec.back().get_ptr(); - int id = buff_vec.size() - 1; - buff_vec.back().set_id(id); - return id; - } -} +template memory_pipe<MemType::CPU, buf_choose_policy::naive>& memory_faucet::get_faucet(); +template memory_pipe<MemType::CPU, buf_choose_policy::sorted_vec>& memory_faucet::get_faucet(); +template memory_pipe<MemType::CPU, buf_choose_policy::find_best_unsorted>& memory_faucet::get_faucet(); -template int memory_pipe<buf_choose_policy::find_best_unsorted>::get_buffer<MemType::CPU>(const size_t required_size, void ** ptr); #ifdef INCLUDE_CUDA -template int memory_pipe<buf_choose_policy::find_best_unsorted>::get_buffer<MemType::GPU>(const size_t required_size, void ** ptr); +template memory_pipe<MemType::GPU, buf_choose_policy::naive>& memory_faucet::get_faucet(); +template memory_pipe<MemType::GPU, buf_choose_policy::sorted_vec>& memory_faucet::get_faucet(); +template memory_pipe<MemType::GPU, buf_choose_policy::find_best_unsorted>& memory_faucet::get_faucet(); #endif -template< > -memory_pipe<buf_choose_policy::naive>& memory_faucet::get_faucet() -{ - static memory_pipe<buf_choose_policy::naive> mem_pipe_naive = memory_pipe<buf_choose_policy::naive>(); - return mem_pipe_naive; -} - -template< > -memory_pipe<buf_choose_policy::sorted_vec>& memory_faucet::get_faucet() -{ - static memory_pipe<buf_choose_policy::sorted_vec> mem_pipe_sorted = memory_pipe<buf_choose_policy::sorted_vec>(); - return mem_pipe_sorted; -} - -template< > -memory_pipe<buf_choose_policy::find_best_unsorted>& memory_faucet::get_faucet() -{ - static memory_pipe<buf_choose_policy::find_best_unsorted> mem_pipe_unsorted = memory_pipe<buf_choose_policy::find_best_unsorted>(); - return mem_pipe_unsorted; -} - - template< MemType mem, buf_choose_policy choose_type > memBuf<mem, choose_type>::memBuf(const size_t required_size) { - memory_pipe<choose_type>& mem_pipe = memory_faucet::get_faucet<choose_type>(); - id = mem_pipe.template get_buffer<mem>(required_size, &buf); + memory_pipe<mem, choose_type>& mem_pipe = memory_faucet::get_faucet<mem, choose_type>(); + id = mf_utils::get_buffer<choose_type>(required_size, mem_pipe.get_buff_vec(), mem, &buf); size = required_size; } template< MemType mem, buf_choose_policy choose_type > memBuf<mem, choose_type>::~memBuf() { - memory_pipe<choose_type>& mem_pipe = memory_faucet::get_faucet<choose_type>(); - mem_pipe.template set_available<mem>(id); + memory_pipe<mem, choose_type>& mem_pipe = memory_faucet::get_faucet<mem, choose_type>(); + mem_pipe.set_available(id); buf = nullptr; } @@ -431,7 +81,7 @@ void* memBuf<mem, choose_type>::ptr() } template< MemType mem, buf_choose_policy choose_type > -int memBuf<mem, choose_type>::get_size() +int memBuf<mem, choose_type>::get_size() const { return size; } diff --git a/Lib/memory-faucet.h b/Lib/memory-faucet.h index adb2111dbff6fe09f56db3236abce9fda1f09c4f..ba99b14d679e41befbc1cad327a3bb8ac5ca2d71 100644 --- a/Lib/memory-faucet.h +++ b/Lib/memory-faucet.h @@ -1,98 +1,16 @@ #pragma once -#include <cstdlib> -#include <vector> -#include <functional> +#include "mf-utils.h" -#include "TemplateParameters.h" - -enum class buf_choose_policy -{ - naive, - sorted_vec, - find_best_unsorted -}; - -template< MemType mem > -class buffer -{ -public: - void *ptr; - size_t allocated_size; - size_t scalar_size; - bool is_free; - int id; - - buffer(const buffer<mem>& other); - buffer(buffer<mem>&& other); - buffer(); - ~buffer(); - buffer(const size_t required_size); - - bool is_available() const; - void* get_ptr(); - bool get_status() const; - size_t get_size() const; - int get_id() const; - - buffer<mem>& operator=(const buffer<mem>& other); - buffer<mem>& operator=(buffer<mem>&& other); - - void reallocate(const size_t required_size); - void set_allocated_size(const size_t required_size); - void set_status(const bool status); - void set_id(const int id); - void set_null_pointer(); -}; - -class memory_pipe_base +template< MemType mem = MemType::CPU, buf_choose_policy choose_type = buf_choose_policy::naive > +class memory_pipe { +private: + std::vector<buffer_base > buff_vec; public: -#ifdef INCLUDE_CUDA - std::vector<buffer<MemType::GPU> > gpu_buff; -#endif - std::vector<buffer<MemType::CPU> > cpu_buff; - - memory_pipe_base(); - ~memory_pipe_base(); - - template< MemType mem > + memory_pipe(/* args */); + ~memory_pipe(); void set_available(const int id); - - template< MemType mem > - std::vector<buffer<mem> >& get_memtyped_vector(); -}; - -template<buf_choose_policy choose_type = buf_choose_policy::naive> -class memory_pipe: public memory_pipe_base -{ -public: - memory_pipe(/* args */) : memory_pipe_base() {} - ~memory_pipe() = default; - - template< MemType mem > - int get_buffer(const size_t required_size, void ** ptr); -}; - -template<> -class memory_pipe<buf_choose_policy::sorted_vec>: public memory_pipe_base -{ -public: - memory_pipe(/* args */) : memory_pipe_base() {} - ~memory_pipe() = default; - - template< MemType mem > - int get_buffer(const size_t required_size, void ** ptr); -}; - -template<> -class memory_pipe<buf_choose_policy::find_best_unsorted>: public memory_pipe_base -{ -public: - memory_pipe(/* args */) : memory_pipe_base() {} - ~memory_pipe() = default; - - template< MemType mem > - int get_buffer(const size_t required_size, void ** ptr); + std::vector<buffer_base >& get_buff_vec(); }; class memory_faucet @@ -104,11 +22,11 @@ private: public: - template<buf_choose_policy choose_type = buf_choose_policy::naive> - static memory_pipe<choose_type>& get_faucet(); + template< MemType mem = MemType::CPU, buf_choose_policy choose_type = buf_choose_policy::naive > + static memory_pipe<mem, choose_type>& get_faucet(); }; -template< MemType mem, buf_choose_policy choose_type = buf_choose_policy::naive > +template< MemType mem = MemType::CPU, buf_choose_policy choose_type = buf_choose_policy::naive > class memBuf { private: @@ -120,5 +38,5 @@ public: memBuf(const size_t required_size); ~memBuf(); void* ptr(); - int get_size(); + int get_size() const; }; \ No newline at end of file diff --git a/Lib/mf-utils.cpp b/Lib/mf-utils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5d7e97cf76a9b16c75da8777afee14201605dcbe --- /dev/null +++ b/Lib/mf-utils.cpp @@ -0,0 +1,155 @@ +#include "mf-utils.h" + +bool mf_utils::free_size_comparator(const buffer_base& obj, const size_t required_size) +{ + if(obj.get_status() == false) + return false; + + return obj.get_size() <= required_size; +} + +bool mf_utils::size_comparator(const size_t required_size, const buffer_base& obj) +{ + return required_size < obj.get_size(); +} + +typename std::vector<buffer_base>::iterator mf_utils::get_lower_bound( + typename std::vector<buffer_base>::iterator first, + typename std::vector<buffer_base>::iterator last, const size_t value, + std::function<bool (const buffer_base&, const size_t) >& comp) +{ + typename std::vector<buffer_base>::iterator it; + typename std::iterator_traits<typename std::vector<buffer_base>::iterator>::difference_type count, step; + count = std::distance(first, last); + + while (count > 0) + { + it = first; + step = count / 2; + it = std::next(it, step); + + if (comp(*it, value)) + { + first = ++it; + count -= step + 1; + } + else + count = step; + } + + return first; +} + +typename std::vector<buffer_base>::iterator mf_utils::get_upper_bound( + typename std::vector<buffer_base>::iterator first, + typename std::vector<buffer_base>::iterator last, const size_t value, + std::function<bool (const size_t, const buffer_base&) >& comp) +{ + typename std::vector<buffer_base>::iterator it; + typename std::iterator_traits<typename std::vector<buffer_base>::iterator>::difference_type count, step; + count = std::distance(first, last); + + while (count > 0) + { + it = first; + step = count / 2; + it = std::next(it, step); + + if (!comp(value, *it)) + { + first = ++it; + count -= step + 1; + } + else + count = step; + } + + return first; +} + +template<> +int mf_utils::get_buffer<buf_choose_policy::naive>(const size_t required_size, + std::vector<buffer_base>& buff_vec, + const MemType mem, + void ** ptr) +{ + const int allocated_buffer_n = buff_vec.size(); + for (int i = 0; i < allocated_buffer_n; i++) + { + const bool is_free = buff_vec[i].get_status(); + const int avail_size = buff_vec[i].get_size(); + + if(is_free == true && required_size <= avail_size) + { + (*ptr) = buff_vec[i].get_ptr(); + buff_vec[i].set_status(false); + return i; + } + } + + buff_vec.push_back(buffer_base(required_size, mem)); + + (*ptr) = buff_vec.back().get_ptr(); + int id = buff_vec.size() - 1; + + buff_vec.back().set_status(false); + buff_vec.back().set_id(id); + + return id; +} + +template<> +int mf_utils::get_buffer<buf_choose_policy::sorted_vec>(const size_t required_size, + std::vector<buffer_base>& buff_vec, + const MemType mem, + void ** ptr) +{ + const int allocated_buffer_n = buff_vec.size(); + for (int i = 0; i < allocated_buffer_n; i++) + { + const bool is_free = buff_vec[i].get_status(); + const int avail_size = buff_vec[i].get_size(); + + if(is_free == true && required_size <= avail_size) + { + (*ptr) = buff_vec[i].get_ptr(); + buff_vec[i].set_status(false); + return i; + } + } + + typename std::vector<buffer_base>::iterator buf_it; + std::function<bool (const size_t, const buffer_base&) > comparator = mf_utils::size_comparator; + buf_it = mf_utils::get_upper_bound (buff_vec.begin(), buff_vec.end(), required_size, comparator); + buf_it = buff_vec.insert(buf_it, buffer_base(required_size, mem)); + (*ptr) = buf_it->get_ptr(); + int id = std::distance(buff_vec.begin(), buf_it); + buff_vec.back().set_id(id); + return id; +} + +template<> +int mf_utils::get_buffer<buf_choose_policy::find_best_unsorted>(const size_t required_size, + std::vector<buffer_base>& buff_vec, + const MemType mem, + void ** ptr) +{ + typename std::vector<buffer_base>::iterator available_buf_it; + std::function<bool (const buffer_base&, const size_t) > comparator = mf_utils::free_size_comparator; + available_buf_it = mf_utils::get_lower_bound (buff_vec.begin(), buff_vec.end(), required_size, comparator); + if(available_buf_it != buff_vec.end()) + { + (*ptr) = available_buf_it->get_ptr(); + int id = std::distance(buff_vec.begin(), available_buf_it); + buff_vec[id].set_status(false); + return id; + } + else + { + buff_vec.push_back(buffer_base(required_size, mem)); + (*ptr) = buff_vec.back().get_ptr(); + int id = buff_vec.size() - 1; + buff_vec.back().set_id(id); + return id; + } +} \ No newline at end of file diff --git a/Lib/mf-utils.h b/Lib/mf-utils.h new file mode 100644 index 0000000000000000000000000000000000000000..bc059905af8c3173db6ca399036bfd104b92916e --- /dev/null +++ b/Lib/mf-utils.h @@ -0,0 +1,33 @@ +#pragma once +#include "buffer.h" +#include <functional> +#include <vector> + +enum class buf_choose_policy +{ + naive, + sorted_vec, + find_best_unsorted +}; + +namespace mf_utils +{ + bool free_size_comparator(const buffer_base& obj, const size_t required_size); + bool size_comparator(const size_t required_size, const buffer_base& obj); + + typename std::vector<buffer_base>::iterator get_lower_bound( + typename std::vector<buffer_base>::iterator first, + typename std::vector<buffer_base>::iterator last, const size_t value, + std::function<bool (const buffer_base&, const size_t) >& comp); + + typename std::vector<buffer_base>::iterator get_upper_bound( + typename std::vector<buffer_base>::iterator first, + typename std::vector<buffer_base>::iterator last, const size_t value, + std::function<bool (const size_t, const buffer_base&) >& comp); + + template<buf_choose_policy choose_type = buf_choose_policy::naive> + int get_buffer(const size_t required_size, + std::vector<buffer_base>& buff_vec, + const MemType mem, + void ** ptr); +} \ No newline at end of file diff --git a/main.cpp b/main.cpp index 6d8ab880eda991129150d0a5dc20a8d0792d0ef9..59f347585edb2b00a6541e08d4cf1faae783fab1 100644 --- a/main.cpp +++ b/main.cpp @@ -25,8 +25,8 @@ int main(void) printf("Start Buf6\n"); memBuf<MemType::CPU> Buf6(required_size6); - printf("Start Buf7\n"); - memBuf<MemType::GPU> Buf7(required_size6); + // printf("Start Buf7\n"); + // memBuf<MemType::GPU> Buf7(required_size6); float* ptr1 = static_cast<float*>(Buf1.ptr()); float* ptr2 = static_cast<float*>(Buf2.ptr());