GCC codegen:pthread_create_key() 与 std::shared_ptr 复制有什么关系?

GCC codegen: What does pthread_create_key() have to do with std::shared_ptr copying?

在比较 std::shared_ptrboost::shared_ptr 的汇编时,我注意到 GCC 为

生成了 一大堆 代码
void test_copy(const std::shared_ptr<int> &sp) { auto copy = sp; }

(https://godbolt.org/z/efTW6MoEh – 超过 70 行汇编程序) 比升压版本,GCC 的 shared_ptr 实现基于:

void test_copy(const boost::shared_ptr<int> &sp) { auto copy = sp; }

(https://godbolt.org/z/3aoGq1f9P – 大约 30 行汇编程序).

特别是,我对 std::shared_ptr 版本中的以下说明感到困惑,我无法(轻易地)在源代码中找到对它的提及。

movq    __gthrw___pthread_key_create(unsigned int*, void (*)(void*))@GOTPCREL(%rip), %rbx

有人可以阐明为什么 std::shared_ptr 生成的代码比 boost::shared_ptr 多得多吗?我是否缺少一些神奇的命令行选项?

我认为这是因为 GCC 的 libstdc++ 正在检查程序是否真的是多线程的。如果不是,则它可以跳过昂贵的锁定指令以原子方式修改引用计数器,并恢复为普通的未锁定指令。 Boost没有此功能,无条件使用锁定指令。

例如,在 libstdc++ 代码中,您会注意到如果指针 __gthrw___pthread_key_create 为空,我们使用简单的非原子指令(行组件的 12 和 16-18)。但如果不是,那么我们将分支到完成锁定 add/xadd 的部分(第 52-58 行)。

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