美文网首页
使用boost::pool<>竟然遇到了严重的性能问题

使用boost::pool<>竟然遇到了严重的性能问题

作者: 卡路里燃烧者 | 来源:发表于2019-01-13 21:14 被阅读0次

    最近在一个模块里面使用了boost::pool<>,结果却遇到严重的性能问题:

    #include <boost/pool/pool.hpp>
    
    class Allocator
    {
    public:
        Allocator()
            : m_pool(1)
        {
        }
    
        void* Allocate(size_t size)
        {
            return m_pool.ordered_malloc(size);
        }
    
        void Free(void* ptr)
        {
            m_pool.ordered_free(ptr);
        }
    
    private:
        boost::pool<> m_pool;
    };
    

    在我们的使用场景中,每次会请求32B~1024B不等的内存块,通过调试发现,malloc_n()和try_malloc_n()中关于寻找n块连续chunk的逻辑会消耗大量的时间,导致性能瓶颈。

    template <typename UserAllocator>
    void * pool<UserAllocator>::ordered_malloc(const size_type n)
    {
        ...
        // 瓶颈所在
        void * ret = store().malloc_n(num_chunks, partition_size);
        ...
    }
    
    template <typename SizeType>
    void * simple_segregated_storage<SizeType>::malloc_n(const size_type n, const size_type partition_size)
    {
        BOOST_POOL_VALIDATE_INTERNALS
        if(n == 0)
            return 0;
        void * start = &first;
        void * iter;
        do
        {
            if (nextof(start) == 0)
                return 0;
            iter = try_malloc_n(start, n, partition_size);
        } while (iter == 0);
        void * const ret = nextof(start);
        nextof(start) = nextof(iter);
        BOOST_POOL_VALIDATE_INTERNALS
        return ret;
    }
    
    template <typename SizeType>
    void * simple_segregated_storage<SizeType>::try_malloc_n(void * & start, size_type n, const size_type partition_size)
    {
        void * iter = nextof(start);
        while (--n != 0)
        {
            void * next = nextof(iter);
            if (next != static_cast<char *>(iter) + partition_size)
            {
                // next == 0 (end-of-list) or non-contiguous chunk found
                start = iter;
                return 0;
            }
            iter = next;
        }
        return iter;
    }
    

    由于我们在构造m_pool的时候指定的“chunk size”为1,所以怀疑是不是指定的“chunk size”过小导致了大量的内存碎片,使得每次寻找连续chunk的时候效率过低,于是考虑调大指定的“chunk size”:

    class Allocator
    {
    public:
        Allocator()
            : m_pool(CHUNK_SIZE)
        {
        }
    
        void* Allocate(size_t size)
        {
            const size_t numChunks = (size + CHUNK_SIZE - 1) / CHUNK_SIZE;
            return m_pool.ordered_malloc(numChunks);
        }
    
        void Free(void* ptr)
        {
            m_pool.ordered_free(ptr);
        }
    
    private:
        // 指定“chunk size”为1024
        static const uint32_t CHUNK_SIZE = 1024;
    
        boost::pool<> m_pool;
    };
    

    最后发现将“chunk size”改为1024,可以解决困扰我们的性能问题,于是打住,便没有再继续深究下去。

    相关文章

      网友评论

          本文标题:使用boost::pool<>竟然遇到了严重的性能问题

          本文链接:https://www.haomeiwen.com/subject/amlldqtx.html