简体   繁体   English

在替换共享指针的内容时优化对allocator的调用

[英]Optimize calls to allocator when replacing the content of a shared pointer

Consider this program: 考虑这个程序:

#include <memory>

struct T {
    T() {}
};

void do_something(std::shared_ptr<T> ptr) {
    // Do something with ptr; might or might not leave
    // other copies of ptr in other variables of the
    // program
}

int main() {
    std::shared_ptr<T> ptr = std::make_shared();
    do_something(ptr);
    // ptr might or might not be the only owner
    ptr = std::make_shared();
    return 0;
}

When make_shared executes for the second time, ptr might or might have other sharing owners, depending on what happens at runtime in do_something . make_shared第二次执行时, ptr可能或可能有其他共享所有者,具体取决于do_something在运行时发生的情况。 If there are no others, ptr destructs and deallocates its previously owned object, when more or less at the same time a new object of the same time is allocated and constructed. 如果没有其他的, ptr破坏并释放其先前拥有的对象,当或多或少同时分配和构造同一时间的新对象时。 Is there any way to avoid the allocation and deallocation, and use the same region for constructing the new object? 有没有办法避免分配和释放,并使用相同的区域来构建新对象? (the target here is to optimize the two calls to the allocator) (这里的目标是优化对分配器的两次调用)

Of course I accept that the new T object will be constructed after the old one will be destructed, while in the code above the opposite happens. 当然我接受新的T对象将在旧的T对象被破坏之后被构造,而在上面的代码中则相反。 So I would like something like ptr.replace<U>(args) which does the following: it decrements ptr 's reference count; 所以我ptr.replace<U>(args)那样执行以下操作:它减少了ptr的引用计数; if the count goes to zero, there are no other weak references and U is the most derived type of the content of ptr , it destructs the owned object and it constructs a new one with arguments args in the same memory region, avoiding calls to the memory allocator. 如果计数变为零,则没有其他弱引用, Uptr内容的派生类型最多,它会破坏拥有的对象,并在同一内存区域构造一个带有参数args的新对象,从而避免调用内存分配器。 Otherwise it behaves like ptr = std::make_shared<U>(args) . 否则它的行为类似于ptr = std::make_shared<U>(args)

Is there anyway to perform this optimization with the current standard library? 无论如何使用当前的标准库执行此优化?

There is no mechanism to count the number of weak_ptr s to a shared object. 没有机制可以将weak_ptr的数量计入共享对象。 You can only query the strong count (via shared_ptr::use_count ). 您只能查询强计数(通过shared_ptr::use_count )。 Note that in multithreaded environments, this is allowed to be an approximate count (ie using a memory_order_relaxed load). 请注意,在多线程环境中,允许这是一个近似计数(即使用memory_order_relaxed加载)。

Are you sure this is a performance bottleneck? 你确定这是性能瓶颈吗?

Consider allocate_shared . 考虑allocate_shared It creates a shared_ptr with an allocator. 它使用分配器创建shared_ptr It is possible to cache the control block of a freed shared_ptr in the allocator, and immediately reuse it in the next allocate_shared call, saving a delete and new. 可以在分配器中缓存释放的shared_ptr的控制块,并立即在下一个allocate_shared调用中重用它,从而保存delete和new。

I doubt that it will make much difference. 我怀疑它会有很大的不同。 In a multithreaded application, this allocator can be nontrivial to get both fast and correct. 在多线程应用程序中,此分配器可以非常重要,以便快速和正确。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM