[英]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. 如果计数变为零,则没有其他弱引用,
U
是ptr
内容的派生类型最多,它会破坏拥有的对象,并在同一内存区域构造一个带有参数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.