【发布时间】:2020-08-26 02:18:54
【问题描述】:
参考GCC website。据说
tls_model 属性设置特定 __thread 变量的线程本地存储模型(请参阅 Thread-Local),在每个变量的基础上覆盖 -ftls-model= 命令行开关。 tls_model 参数应该是 global-dynamic、local-dynamic、initial-exec 或 local-exec 之一。并非所有目标都支持此属性。
为了查看为不同 TLS 模型生成的程序集的差异,创建了一个包含三个 __thread 变量的类。
#include <cstdint>
class Holder
{
public:
static int32_t calc();
static int32_t calc2();
static int32_t calc3();
static __thread int32_t value __attribute__ ((tls_model("initial-exec")));
static __thread int32_t value2 __attribute__ ((tls_model("local-dynamic")));
static __thread int32_t value3;
};
__thread int32_t Holder::value;
__thread int32_t Holder::value2;
__thread int32_t Holder::value3;
int32_t Holder::calc()
{
return value * 2;
}
int32_t Holder::calc2()
{
return value2 * 2;
}
int32_t Holder::calc3()
{
return value3 * 2;
}
这是使用-c -shared -fPIC -O3 标志编译的。但是,请注意,该属性不会在相应的计算函数中产生任何差异。 (在相应的计算函数中都使用__tls_get_addr。)但是,如果添加了-ftls-model=initial-exec 标志,它确实会改变TLS 模型,但都会被覆盖以使用inital-exec(所有计算函数都使用@gottpoff(%rip))
使用在线编译器资源管理器,发现 clang (LLVM) 和 icc 似乎都尊重属性,但不尊重 gcc。它似乎也与 GCC 网站中的描述相矛盾(基于每个变量覆盖)。可以在this 上试用并切换到不同的编译器。
GCC 是否有理由删除了覆盖每个变量设置的能力?还是我做错了什么或有错误的期望?
提前感谢您的帮助和解释。
【问题讨论】:
-
这是在 Linux 上,对吧?我添加了那个标签。我假设基于
@gottpoff(%rip)- 我认为无论 Windows 使用什么都不称为 GOT,但我不确定 MacOS。 -
是的,它在 Linux 上。感谢您添加标签。
标签: linux gcc x86-64 thread-local-storage