使用shared_ptr的开销和实现

时间:2012-06-05 17:45:07

标签: c++ c++11 shared-ptr

简短介绍:我正在研究多线程代码,我必须在两个线程之间共享动态分配的对象。为了使我的代码更清晰(并且更不容易出错),我想明确地“删除”每个线程中的对象,这就是我想使用shared_ptr的原因。

第一个问题:

我想知道-> operatorshared_ptr的实施是否在运行时期间有一些额外的开销(例如大于unique_ptr)。我正在谈论的对象通常是在创建后仅复制一次的longlife实例(当我在线程之间分发它们时),然后我只访问这些对象的方法和字段。

我知道,shared_ptr仅保护引用计数。

第二个问题:

libstdc ++中shared_ptr的优化程度如何?它总是使用互斥量还是利用原子操作(我专注于x86和ARM平台)?

2 个答案:

答案 0 :(得分:14)

  

第一个问题:使用operator->

我看到的所有实现都在T*类中有shared_ptr<T>的本地缓存,因此该字段位于堆栈中,operator->因此具有与使用堆栈本地T*:根本没有开销。

  

第二个问题:mutex / atomics

我希望libstdc ++在x86平台上使用atomics,无论是通过标准工具还是特定的g ++内在函数(在旧版本中)。我相信Boost实现已经这样做了。

但是,我不能对ARM发表评论。

注意:C ++ 11引入了移动语义,在shared_ptr的使用中自然避免了许多副本。

注意:请阅读shared_ptr here的正确用法,您可以使用shared_ptrconst或不{{1}})的引用来避免大部分副本/一般的破坏,所以那些表现并不太重要。

答案 1 :(得分:13)

GCC的shared_ptr将在单线程代码中不使用锁定或原子。在多线程代码中,如果CPU支持原子比较和交换指令,它将使用原子操作,否则引用计数受互斥锁保护。在i486及更高版本上它使用原子,i386不支持cmpxchg,因此使用基于互斥锁的实现。我相信ARM使用原子技术用于ARMv7架构以及稍后。

(这同样适用于std::shared_ptrstd::tr1::shared_ptr。)