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_ptr
和 boost::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
的引用中。
在比较 std::shared_ptr
和 boost::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
的引用中。