Mar*_*utz 8 c++ assembly gnu x86-64 shared-ptr
虽然比较组件,用于std::shared_ptr
对boost::shared_ptr
,我注意到,GCC生成一大堆更多的代码
void test_copy(const std::shared_ptr<int> &sp) { auto copy = sp; }
Run Code Online (Sandbox Code Playgroud)
( https://godbolt.org/z/efTW6MoEh – 超过 70 行汇编程序) 而不是 boost 版本,GCC 的 shared_ptr 实现基于该版本:
void test_copy(const boost::shared_ptr<int> &sp) { auto copy = sp; }
Run Code Online (Sandbox Code Playgroud)
(https://godbolt.org/z/3aoGq1f9P – 大约 30 行汇编程序)。
特别是,我对std::shared_ptr
版本中的以下说明感到困惑,我在来源中(很容易)找不到提到的说明。
movq __gthrw___pthread_key_create(unsigned int*, void (*)(void*))@GOTPCREL(%rip), %rbx
Run Code Online (Sandbox Code Playgroud)
有人能解释一下为什么std::shared_ptr
生成比 多得多的代码boost::shared_ptr
吗?我错过了一些神奇的命令行选项吗?
我认为这是因为 GCC 的 libstdc++ 正在检查程序是否实际上是多线程的。如果不是,那么它可以跳过昂贵的锁定指令来原子地修改引用计数器,并恢复到普通的解锁指令。Boost 没有这个特性并且无条件地使用锁定指令。
例如,在 libstdc++ 代码中,您会注意到如果指针__gthrw___pthread_key_create
为空,我们会[rbp+8]
使用简单的非原子指令(程序集的第 12 和 16-18 行)递增和递减引用计数器 at 。但如果不是,那么我们将分支到add/xadd
完成锁定的部分(第 52-58 行)。
我还没有真正深入研究源代码,但我怀疑这些细节隐藏在对_Lock_policy
.