gcc __thread 是做什么的?
What does gcc __thread do?
我真的很困惑 gcc __thread
的关键字在背后做了什么。
谁能给我一些信息吗?
它将变量声明为 thread local 与 C++11 thread_local
关键字的方式非常相似,重要的区别在于 thread_local
允许静态初始化,而 __thread
没有。
如 this answer.
中所述,进行静态初始化的能力可能会对性能产生显着影响(每次访问的函数调用)
线程本地意味着访问该变量的每个线程都将看到一个单独的、不同的变量,就好像它们确实是具有不同名称的变量一样(尽管它们在源级别上是相同的名称)。
编译器究竟做了什么来实现这个是实现定义的和平台相关的。典型的实现(不同版本的 GCC 之间不同)包括调用例如Linux 下的 get_thread_area
和 Windows 下的 TlsAlloc
/TlsGetValue
31=] 否则,或者每次访问都会有明显的开销 (Windows)。
备选方案包括从线程环境块获取指针并执行 table 查找(这也是 TlsGetValue
函数在内部执行的操作)或具有一个单独的可写静态数据段,该数据段是按线程选择的访问(这已经是实现 errno
多年来所做的),或者只是在程序启动时在堆栈底部保留一个小区域,因为堆栈上的任何内容根据定义都是线程本地的。
您的特定编译器版本究竟使用哪种方法只有通过编译和反汇编程序(或通过挖掘编译器源代码)才能知道。
您将遇到的开销范围可能从 "just two memory acesses instead of one" 到函数调用后跟一两打指令,甚至在最坏的情况下甚至是系统调用。
我真的很困惑 gcc __thread
的关键字在背后做了什么。
谁能给我一些信息吗?
它将变量声明为 thread local 与 C++11 thread_local
关键字的方式非常相似,重要的区别在于 thread_local
允许静态初始化,而 __thread
没有。
如 this answer.
线程本地意味着访问该变量的每个线程都将看到一个单独的、不同的变量,就好像它们确实是具有不同名称的变量一样(尽管它们在源级别上是相同的名称)。
编译器究竟做了什么来实现这个是实现定义的和平台相关的。典型的实现(不同版本的 GCC 之间不同)包括调用例如Linux 下的 get_thread_area
和 Windows 下的 TlsAlloc
/TlsGetValue
31=] 否则,或者每次访问都会有明显的开销 (Windows)。
备选方案包括从线程环境块获取指针并执行 table 查找(这也是 TlsGetValue
函数在内部执行的操作)或具有一个单独的可写静态数据段,该数据段是按线程选择的访问(这已经是实现 errno
多年来所做的),或者只是在程序启动时在堆栈底部保留一个小区域,因为堆栈上的任何内容根据定义都是线程本地的。
您的特定编译器版本究竟使用哪种方法只有通过编译和反汇编程序(或通过挖掘编译器源代码)才能知道。
您将遇到的开销范围可能从 "just two memory acesses instead of one" 到函数调用后跟一两打指令,甚至在最坏的情况下甚至是系统调用。