TLS 模型上的 GCC 公共变量属性
GCC Common Variable Attribute on TLS model
参考GCC website。据称
The tls_model attribute sets thread-local storage model (see Thread-Local) of a particular __thread variable, overriding -ftls-model= command-line switch on a per-variable basis. The tls_model argument should be one of global-dynamic, local-dynamic, initial-exec or local-exec. Not all targets support this attribute.
为了研究为不同 TLS 模型生成的程序集的差异,创建了一个包含三个 __thread 变量的 class。
#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
标志编译的。但是,请注意,该属性不会在相应的计算函数中产生任何差异。 (都在相应的 calc 函数中使用 __tls_get_addr
。)但是,如果添加了 -ftls-model=initial-exec
标志,它确实会更改 TLS 模型,但都会被覆盖以使用 inital-exec(所有 calc 函数都使用 @gottpoff(%rip)
)
使用在线编译器资源管理器,发现 clang (LLVM) 和 icc 似乎都支持该属性,但不支持 gcc。它似乎也与 GCC 网站中的描述相矛盾(在每个变量的基础上覆盖)。可以在 this 上尝试一下,然后切换到不同的编译器。
GCC 取消覆盖每个变量设置的能力是否有原因?还是我做错了什么或抱有错误的期望?
提前感谢您的帮助和解释。
这是一个错误,可能在 C++ 前端,and/or 在属性合并代码中。如果您从定义的声明中移动或复制属性,它会按预期工作。如果您删除定义,只保留声明,它也可以根据文档工作。基本上,每个定义似乎都没有正确地继承前面声明的属性。这值得在 https://gnu.gnu.org/bugzilla
提交错误报告
参考GCC website。据称
The tls_model attribute sets thread-local storage model (see Thread-Local) of a particular __thread variable, overriding -ftls-model= command-line switch on a per-variable basis. The tls_model argument should be one of global-dynamic, local-dynamic, initial-exec or local-exec. Not all targets support this attribute.
为了研究为不同 TLS 模型生成的程序集的差异,创建了一个包含三个 __thread 变量的 class。
#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
标志编译的。但是,请注意,该属性不会在相应的计算函数中产生任何差异。 (都在相应的 calc 函数中使用 __tls_get_addr
。)但是,如果添加了 -ftls-model=initial-exec
标志,它确实会更改 TLS 模型,但都会被覆盖以使用 inital-exec(所有 calc 函数都使用 @gottpoff(%rip)
)
使用在线编译器资源管理器,发现 clang (LLVM) 和 icc 似乎都支持该属性,但不支持 gcc。它似乎也与 GCC 网站中的描述相矛盾(在每个变量的基础上覆盖)。可以在 this 上尝试一下,然后切换到不同的编译器。
GCC 取消覆盖每个变量设置的能力是否有原因?还是我做错了什么或抱有错误的期望?
提前感谢您的帮助和解释。
这是一个错误,可能在 C++ 前端,and/or 在属性合并代码中。如果您从定义的声明中移动或复制属性,它会按预期工作。如果您删除定义,只保留声明,它也可以根据文档工作。基本上,每个定义似乎都没有正确地继承前面声明的属性。这值得在 https://gnu.gnu.org/bugzilla
提交错误报告