GCC 代码生成器:pthread_create_key() 与 std::shared_ptr 复制有什么关系?

Mar*_*utz 8 c++ assembly gnu x86-64 shared-ptr

虽然比较组件,用于std::shared_ptrboost::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吗?我错过了一些神奇的命令行选项吗?

Nat*_*dge 6

我认为这是因为 GCC 的 libstdc++ 正在检查程序是否实际上是多线程的。如果不是,那么它可以跳过昂贵的锁定指令来原子地修改引用计数器,并恢复到普通的解锁指令。Boost 没有这个特性并且无条件地使用锁定指令。

例如,在 libstdc++ 代码中,您会注意到如果指针__gthrw___pthread_key_create为空,我们会[rbp+8]使用简单的非原子指令(程序集的第 12 和 16-18 行)递增和递减引用计数器 at 。但如果不是,那么我们将分支到add/xadd完成锁定的部分(第 52-58 行)。

我还没有真正深入研究源代码,但我怀疑这些细节隐藏在对_Lock_policy.