Synchronized_pool_resource实际如何工作? [英] How the synchronized_pool_resource actually works?

查看:128
本文介绍了Synchronized_pool_resource实际如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究C ++ 17中的多态内存分配.我修改了一个使用monotonic_buffer_resource进行矢量分配的示例,以使用synceded_pool_resource.我检测到奇怪的行为.具体来说,有很多内存分配,仅用于向量中的两个加法.我没有运行基准测试,但我认为这会对性能造成巨大的损失

I am studying about the polymorphic memory allocation in C++17. I modified an example which uses monotonic_buffer_resource for vector allocations to use a synchronized_pool_resource. I detected a strange behavior. Specifically , there are many memory allocations , just for two additions in the vector. I did not run benchmarks but I think that this a huge penalty for the performance

该程序是使用O2编译的 g ++ -std = c ++ 17 -O2 -Wall -pedantic

The program was compiled using the O2 g++ -std=c++17 -O2 -Wall -pedantic

下面是代码

class debug_resource : public std::pmr::memory_resource {

public:
    explicit debug_resource(std::string name,
        std::pmr::memory_resource* up = std::pmr::get_default_resource())
        : _name{ std::move(name) }, _upstream{ up }
    { }

    void* do_allocate(size_t bytes, size_t alignment) override {
        std::cout << _name << " do_allocate(): " << bytes << '\n';
        void* ret = _upstream->allocate(bytes, alignment);
        return ret;
    }
    void do_deallocate(void* ptr, size_t bytes, size_t alignment) override {
        std::cout << _name << " do_deallocate(): " << bytes << '\n';
        _upstream->deallocate(ptr, bytes, alignment);
    }
    bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override {
        return this == &other;
    }

private:
    std::string _name;
    std::pmr::memory_resource* _upstream;
};
int main()
{
  
    debug_resource default_dbg{ "default" };
    std::pmr::synchronized_pool_resource pool(&default_dbg);
  //  debug_resource dbg{ "pool", &pool };
    std::pmr::vector<std::string> strings{ &pool };

   strings.emplace_back("Hello Short String");
   strings.emplace_back("Hello Short String 2");
}

控制台输出如下

默认do_allocate():32
默认的do_allocate():528
默认的do_allocate():32
默认的do_allocate():528
默认的do_allocate():1000
默认的do_allocate():192
默认do_allocate():968
默认的do_allocate():192

default do_allocate(): 32
default do_allocate(): 528
default do_allocate(): 32
default do_allocate(): 528
default do_allocate(): 1000
default do_allocate(): 192
default do_allocate(): 968
default do_allocate(): 192

默认do_deallocate():528
默认的do_deallocate():32
默认的do_deallocate():1000
默认的do_deallocate():192
默认do_deallocate():968
默认的do_deallocate():192
默认的do_deallocate():528
默认的do_deallocate():32

default do_deallocate(): 528
default do_deallocate(): 32
default do_deallocate(): 1000
default do_deallocate(): 192
default do_deallocate(): 968
default do_deallocate(): 192
default do_deallocate(): 528
default do_deallocate(): 32

推荐答案

答案在函数描述中: https://en.cppreference.com/w/cpp/memory/synchronized_pool_resource

它由一个池集合组成,该池可为不同的请求提供服务块大小.每个池管理一组大块,然后分成均匀大小的块.

It consists of a collection of pools that serves request for different block sizes. Each pool manages a collection of chunks that are then divided into blocks of uniform size.

对do_allocate的调用被分派到服务最小的池中块可容纳要求的尺寸.

Calls to do_allocate are dispatched to the pool serving the smallest blocks accommodating the requested size.

内存耗尽导致下一个分配请求该池从上游分配额外的内存块分配器以补充池.获得的块大小增加几何.

Exhausting memory in the pool causes the next allocation request for that pool to allocate an additional chunk of memory from the upstream allocator to replenish the pool. The chunk size obtained increases geometrically.

最大块大小和最大块大小可以通过传递来调整一个std :: pmr :: pool_options结构为其构造器.

因此,池实际上是内存块的集合.并在必要时增加此集合.因此有多种分配方式.

So a pool is actually a collection of memory blocks. And this collection is increased when necessary. Hence multiple allocations.

要减少分配数量,您可以尝试使用 std :: pmr ::pool_options .

To decrease the number of allocations you can try playing with std::pmr::pool_options.

这篇关于Synchronized_pool_resource实际如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆