gpt4 book ai didi

c++ - gcc 在这里做什么来让每个线程运行一次这段代码?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:29:43 24 4
gpt4 key购买 nike

我刚刚遇到了这种为每个线程运行一次代码的技术。我不知道它在最低级别上是如何工作的。特别是,fs 指向什么? .zero 8 是什么意思?标识符是 @tpoff 是有原因的吗?

int foo();

void bar()
{
thread_local static auto _ = foo();
}

输出(带-O2):

bar():
cmp BYTE PTR fs:guard variable for bar()::_@tpoff, 0
je .L8
ret
.L8:
sub rsp, 8
call foo()
mov BYTE PTR fs:guard variable for bar()::_@tpoff, 1
add rsp, 8
ret
guard variable for bar()::_:
.zero 8

最佳答案

fs 段基址是线程本地存储的地址(至少在 x86-64 Linux 上)。

.zero 8 保留 8 个字节的零(大概在 BSS 中)。查看 GAS 手册:https://sourceware.org/binutils/docs/as/Zero.html , 链接在 https://stackoverflow.com/tags/x86/info .

@tpoff 大概是指相对于线程本地存储来解决它,可能代表线程偏移量,我不知道。


它的其余部分看起来类似于 gcc 通常为需要运行时初始化程序的 static 局部变量所做的事情:一个每次进入函数时都会检查的保护变量,在已经-初始化案例。

1 字节的保护变量在线程本地存储中。实际的 _ 本身被优化掉了,因为它从未被读取。请注意,在 foo 返回后没有存储 eax

顺便说一句,_ 是一个奇怪的(错误的)变量名选择。很容易错过它,并且可能保留供实现使用。


它在这里有一个很好的优化:通常(对于非线程本地 static int var = foo();)如果它发现 guard 变量还没有被初始化,它需要一个线程- 确保只有一个线程实际执行初始化(本质上是获取锁)的安全方法。

但是这里每个线程都有自己的保护变量(而且应该第一次运行foo(),不管其他线程在做什么)所以它不需要调用 run_once 函数来实现互斥。

(抱歉,我的回答很简短,稍后我可能会在 https://godbolt.org/ 上用一个非线程本地 static 局部变量的示例来扩展它。或者找到一个关于它的 SO Q&A。)

关于c++ - gcc 在这里做什么来让每个线程运行一次这段代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54270228/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com