Skip to content
Snippets Groups Projects
memory-holder.cpp 11.7 KiB
Newer Older
数学の武士'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