Skip to content
Snippets Groups Projects
memory-holder.cpp 11.7 KiB
Newer Older
  • Learn to ignore specific revisions
  • 数学の武士's avatar
    .
    数学の武士 committed
    #include "memory-holder.h"
    #include "MemoryProcessing.h"
    #ifdef INCLUDE_CUDA
    #include "MemoryProcessing.cuh"
    #endif
    
    数学の武士's avatar
    数学の武士 committed
    
    
    数学の武士's avatar
    .
    数学の武士 committed
    #include <algorithm>
    
    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)
    {
    
    数学の武士's avatar
    .  
    数学の武士 committed
        allocated_size = 0;
    
    数学の武士's avatar
    .
    数学の武士 committed
        reallocate(required_size);
        scalar_size = 0;
        is_free = false;
    }
    
    template< MemType mem >
    
    数学の武士's avatar
    .  
    数学の武士 committed
    bool free_size_comparator(const buffer<mem>& obj, const size_t required_size)
    
    数学の武士's avatar
    .
    数学の武士 committed
    {
        if(obj.get_status() == false)
            return false;
    
        return obj.get_size() <= required_size;
    }
    
    
    数学の武士's avatar
    .  
    数学の武士 committed
    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);
    
    数学の武士's avatar
    .  
    数学の武士 committed
    #ifdef INCLUDE_CUDA
    
    数学の武士's avatar
    .  
    数学の武士 committed
    template bool size_comparator(const size_t required_size, const buffer<MemType::GPU>& obj);
    
    数学の武士's avatar
    .  
    数学の武士 committed
    #endif
    
    数学の武士's avatar
    .
    数学の武士 committed
    
    template< MemType mem >
    
    数学の武士's avatar
    .  
    数学の武士 committed
    void* buffer<mem>::get_ptr()
    
    数学の武士's avatar
    .
    数学の武士 committed
    {
        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;
    }
    
    
    数学の武士's avatar
    .  
    数学の武士 committed
    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 >
    buffer<mem>::buffer(const buffer<mem>& other)
    {
        allocated_size = 0;
        reallocate(other.get_size());
        is_free = other.get_status();
        id = other.get_id();
    }
    
    
    数学の武士's avatar
    .
    数学の武士 committed
    template< MemType mem >
    buffer<mem>& buffer<mem>::operator=(buffer<mem>& other)
    {
        if (this == &other)
            return *this;
    
    数学の武士's avatar
    .  
    数学の武士 committed
    
    
    数学の武士's avatar
    .
    数学の武士 committed
        std::swap(ptr, other.ptr);
    
    数学の武士's avatar
    .  
    数学の武士 committed
        allocated_size = other.get_size();
        other.set_allocated_size(size_t(0));
        is_free = other.get_status();
        id = other.get_id();
        return *this;
    }
    
    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();
    
    
    数学の武士's avatar
    .
    数学の武士 committed
        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>;
    
    数学の武士's avatar
    .  
    数学の武士 committed
    #ifdef INCLUDE_CUDA
    
    数学の武士's avatar
    .
    数学の武士 committed
    template class buffer<MemType::GPU>;
    
    数学の武士's avatar
    .  
    数学の武士 committed
    #endif
    
    数学の武士's avatar
    .
    数学の武士 committed
    
    
    数学の武士's avatar
    .  
    数学の武士 committed
    memory_pipline_base::memory_pipline_base()
    
    数学の武士's avatar
    .
    数学の武士 committed
    {
    
    数学の武士's avatar
    .  
    数学の武士 committed
    #ifdef INCLUDE_CUDA
    
    数学の武士's avatar
    .
    数学の武士 committed
        gpu_buff = std::vector<buffer<MemType::GPU> > ();
    
    数学の武士's avatar
    .  
    数学の武士 committed
    #endif
    
    数学の武士's avatar
    .
    数学の武士 committed
        cpu_buff = std::vector<buffer<MemType::CPU> > ();
    }
    
    
    数学の武士's avatar
    .  
    数学の武士 committed
    memory_pipline_base::~memory_pipline_base()
    
    数学の武士's avatar
    .
    数学の武士 committed
    {
    
    数学の武士's avatar
    .  
    数学の武士 committed
    #ifdef INCLUDE_CUDA
    
    数学の武士's avatar
    .
    数学の武士 committed
        gpu_buff.clear();
    
    数学の武士's avatar
    .  
    数学の武士 committed
    #endif
    
    数学の武士's avatar
    .
    数学の武士 committed
        cpu_buff.clear();
    }
    
    template< MemType mem >
    
    数学の武士's avatar
    .  
    数学の武士 committed
    std::vector<buffer<mem> >& memory_pipline_base::get_memtyped_vector()
    
    数学の武士's avatar
    .
    数学の武士 committed
    {
        return cpu_buff;
    }
    
    
    数学の武士's avatar
    .  
    数学の武士 committed
    #ifdef INCLUDE_CUDA
    
    数学の武士's avatar
    .
    数学の武士 committed
    template<>
    
    数学の武士's avatar
    .  
    数学の武士 committed
    std::vector<buffer<MemType::GPU> >& memory_pipline_base::get_memtyped_vector()
    
    数学の武士's avatar
    .
    数学の武士 committed
    {
        return gpu_buff;
    }
    
    数学の武士's avatar
    .  
    数学の武士 committed
    #endif
    
    数学の武士's avatar
    .
    数学の武士 committed
    
    template< MemType mem >
    
    数学の武士's avatar
    .  
    数学の武士 committed
    void memory_pipline_base::set_available(const int id)
    {
    
    数学の武士's avatar
    .  
    数学の武士 committed
        get_memtyped_vector<mem>()[id].set_status(true);
    
    数学の武士's avatar
    .  
    数学の武士 committed
    }
    
    template void memory_pipline_base::set_available<MemType::CPU>(const int id);
    #ifdef INCLUDE_CUDA
    template void memory_pipline_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)
    {
        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;
            std::next(it, step);
     
            if (comp(*it, value))
            {
                first = ++it;
                count -= step + 1;
            }
            else
                count = step;
        }
     
        return first;
    }
    
    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
    
    数学の武士's avatar
    .  
    数学の武士 committed
    template typename std::vector<buffer<MemType::GPU>>::iterator get_lower_bound<MemType::GPU >(typename std::vector<buffer<MemType::GPU>>::iterator first, 
    
    数学の武士's avatar
    .  
    数学の武士 committed
        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)
    
    数学の武士's avatar
    .
    数学の武士 committed
    {
    
    数学の武士's avatar
    .  
    数学の武士 committed
        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;
            std::next(it, step);
     
            if (!comp(value, *it))
            {
                first = ++it;
                count -= step + 1;
            } 
            else
                count = step;
        }
     
        return first;
    }
    
    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
    
    数学の武士's avatar
    .  
    数学の武士 committed
    template typename std::vector<buffer<MemType::GPU>>::iterator get_upper_bound<MemType::GPU >(typename std::vector<buffer<MemType::GPU>>::iterator first, 
    
    数学の武士's avatar
    .  
    数学の武士 committed
        typename std::vector<buffer<MemType::GPU>>::iterator last, const size_t value, std::function<bool (const size_t, const buffer<MemType::GPU>&)>& );
    #endif
    
    template<buf_choose_policy choose_type>
    template< MemType mem >
    int memory_pipline<choose_type>::get_buffer(const size_t required_size, void *& ptr)
    {
    
    数学の武士's avatar
    .  
    数学の武士 committed
        std::vector<buffer<mem> >& buff_vec = get_memtyped_vector<mem>();
    
    数学の武士's avatar
    .  
    数学の武士 committed
        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();
                return i;
            }
        }
    
        buff_vec.push_back(buffer<mem>(required_size));
        ptr = buff_vec.back().get_ptr();
        int id = buff_vec.size() - 1;
        return id;
    }
    
    template int memory_pipline<buf_choose_policy::naiv>::get_buffer<MemType::CPU>(const size_t required_size, void *& ptr);
    #ifdef INCLUDE_CUDA
    template int memory_pipline<buf_choose_policy::naiv>::get_buffer<MemType::GPU>(const size_t required_size, void *& ptr);
    #endif
    
    template< MemType mem >
    int memory_pipline<buf_choose_policy::sorted_vec>::get_buffer(const size_t required_size, void *& ptr)
    {
    
    数学の武士's avatar
    .  
    数学の武士 committed
        std::vector<buffer<mem> >& buff_vec = get_memtyped_vector<mem>();
    
    数学の武士's avatar
    .  
    数学の武士 committed
        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();
                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);
    
        return id;
    }
    
    template int memory_pipline<buf_choose_policy::sorted_vec>::get_buffer<MemType::CPU>(const size_t required_size, void *& ptr);
    #ifdef INCLUDE_CUDA
    template int memory_pipline<buf_choose_policy::sorted_vec>::get_buffer<MemType::GPU>(const size_t required_size, void *& ptr);
    #endif
    
    template< MemType mem >
    int memory_pipline<buf_choose_policy::find_best_unsorted>::get_buffer(const size_t required_size, void *& ptr)
    {
    
    数学の武士's avatar
    .  
    数学の武士 committed
        std::vector<buffer<mem> >& buff_vec = get_memtyped_vector<mem>();
    
    数学の武士's avatar
    .
    数学の武士 committed
        typename std::vector<buffer<mem>>::iterator available_buf_it;
    
    数学の武士's avatar
    .  
    数学の武士 committed
        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())
    
    数学の武士's avatar
    .
    数学の武士 committed
        {    
            ptr = available_buf_it->get_ptr();
    
    数学の武士's avatar
    .  
    数学の武士 committed
            int id = std::distance(buff_vec.begin(), available_buf_it);
    
    数学の武士's avatar
    .
    数学の武士 committed
            return id;
        }
        else
        {
    
    数学の武士's avatar
    .  
    数学の武士 committed
            buff_vec.push_back(buffer<mem>(required_size));
            ptr = buff_vec.back().get_ptr();
            int id = buff_vec.size() - 1;
    
    数学の武士's avatar
    .
    数学の武士 committed
            return id;
        }
    }
    
    
    数学の武士's avatar
    .  
    数学の武士 committed
    template int memory_pipline<buf_choose_policy::find_best_unsorted>::get_buffer<MemType::CPU>(const size_t required_size, void *& ptr);
    
    数学の武士's avatar
    .  
    数学の武士 committed
    #ifdef INCLUDE_CUDA
    
    数学の武士's avatar
    .  
    数学の武士 committed
    template int memory_pipline<buf_choose_policy::find_best_unsorted>::get_buffer<MemType::GPU>(const size_t required_size, void *& ptr);
    
    数学の武士's avatar
    .  
    数学の武士 committed
    #endif
    
    数学の武士's avatar
    .
    数学の武士 committed
    
    
    数学の武士's avatar
    数学の武士 committed
    template< >
    memory_pipline<buf_choose_policy::naiv>& memory_faucet::get_faucet()
    
    数学の武士's avatar
    .
    数学の武士 committed
    {
    
    数学の武士's avatar
    数学の武士 committed
        static memory_pipline<buf_choose_policy::naiv> mem_pipe_naiv;
    
    数学の武士's avatar
    .  
    数学の武士 committed
        return mem_pipe_naiv;
    
    数学の武士's avatar
    .
    数学の武士 committed
    }
    
    
    数学の武士's avatar
    .  
    数学の武士 committed
    template< >
    
    数学の武士's avatar
    数学の武士 committed
    memory_pipline<buf_choose_policy::sorted_vec>& memory_faucet::get_faucet()
    
    数学の武士's avatar
    .  
    数学の武士 committed
    {
    
    数学の武士's avatar
    数学の武士 committed
        static memory_pipline<buf_choose_policy::sorted_vec> mem_pipe_sorted;
    
    数学の武士's avatar
    .  
    数学の武士 committed
        return mem_pipe_sorted;
    }
    
    数学の武士's avatar
    .
    数学の武士 committed
    
    
    数学の武士's avatar
    .  
    数学の武士 committed
    template< >
    
    数学の武士's avatar
    数学の武士 committed
    memory_pipline<buf_choose_policy::find_best_unsorted>& memory_faucet::get_faucet()
    
    数学の武士's avatar
    .
    数学の武士 committed
    {
    
    数学の武士's avatar
    数学の武士 committed
        static memory_pipline<buf_choose_policy::find_best_unsorted> mem_pipe_unsorted;
    
    数学の武士's avatar
    .  
    数学の武士 committed
        return mem_pipe_unsorted;
    
    数学の武士's avatar
    .
    数学の武士 committed
    }
    
    
    数学の武士's avatar
    .  
    数学の武士 committed
    
    template< MemType mem, buf_choose_policy choose_type >
    memBuf<mem, choose_type>::memBuf(const size_t required_size)
    
    数学の武士's avatar
    .
    数学の武士 committed
    {
    
    数学の武士's avatar
    数学の武士 committed
        memory_pipline<choose_type>& mem_pipe = memory_faucet::get_faucet<choose_type>();
        id = mem_pipe.template get_buffer<mem>(required_size, buf);
    
    数学の武士's avatar
    .
    数学の武士 committed
        size = required_size;
    }
    
    
    数学の武士's avatar
    .  
    数学の武士 committed
    template< MemType mem, buf_choose_policy choose_type >
    memBuf<mem, choose_type>::~memBuf()
    
    数学の武士's avatar
    .
    数学の武士 committed
    {
    
    数学の武士's avatar
    数学の武士 committed
        memory_pipline<choose_type>& mem_pipe = memory_faucet::get_faucet<choose_type>();
        mem_pipe.template set_available<mem>(id);
    
    数学の武士's avatar
    .
    数学の武士 committed
    }
    
    
    数学の武士's avatar
    .  
    数学の武士 committed
    template< MemType mem, buf_choose_policy choose_type >
    void* memBuf<mem, choose_type>::ptr()
    
    数学の武士's avatar
    .
    数学の武士 committed
    {
        return buf;
    }
    
    
    数学の武士's avatar
    .  
    数学の武士 committed
    template< MemType mem, buf_choose_policy choose_type >
    int memBuf<mem, choose_type>::get_size()
    
    数学の武士's avatar
    .
    数学の武士 committed
    {
        return size;
    }
    
    
    数学の武士's avatar
    .  
    数学の武士 committed
    template class memBuf<MemType::CPU, buf_choose_policy::naiv>;
    template class memBuf<MemType::CPU, buf_choose_policy::sorted_vec>;
    template class memBuf<MemType::CPU, buf_choose_policy::find_best_unsorted>;
    
    
    数学の武士's avatar
    .  
    数学の武士 committed
    #ifdef INCLUDE_CUDA
    
    数学の武士's avatar
    .  
    数学の武士 committed
    template class memBuf<MemType::GPU, buf_choose_policy::naiv>;
    template class memBuf<MemType::GPU, buf_choose_policy::sorted_vec>;
    template class memBuf<MemType::GPU, buf_choose_policy::find_best_unsorted>;
    
    数学の武士's avatar
    .  
    数学の武士 committed
    #endif