Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
本地线程的成本 < C++ >添加 thRead本地/代码>存储作为语言特征,我想知道一些事情: thead\u local的成本可能是多少? 在记忆中 用于读写操作 与此相关:操作系统通常如何实现这一点?似乎任何声明的thread\u local都必须为每个创建的线程提供特定于线程的存储空间_C++_Thread Local Storage - Fatal编程技术网

本地线程的成本 < C++ >添加 thRead本地/代码>存储作为语言特征,我想知道一些事情: thead\u local的成本可能是多少? 在记忆中 用于读写操作 与此相关:操作系统通常如何实现这一点?似乎任何声明的thread\u local都必须为每个创建的线程提供特定于线程的存储空间

本地线程的成本 < C++ >添加 thRead本地/代码>存储作为语言特征,我想知道一些事情: thead\u local的成本可能是多少? 在记忆中 用于读写操作 与此相关:操作系统通常如何实现这一点?似乎任何声明的thread\u local都必须为每个创建的线程提供特定于线程的存储空间,c++,thread-local-storage,C++,Thread Local Storage,存储空间:变量的大小*线程数,或者可能(sizeof(var)+sizeof(var*))*线程数 有两种实现线程本地存储的基本方法: 使用某种获取当前内核线程信息的系统调用。斯洛 使用一些指针,可能是在处理器寄存器中,内核在每个线程上下文开关处正确设置该指针-与所有其他寄存器同时设置。便宜 在英特尔平台上,变体2通常通过某些段寄存器(我不记得是FS还是GS)实现。GCC和MSVC都支持这一点。因此,访问时间大约与全局变量的访问时间一样快 这也是可能的,但我还没有在实践中看到,它是通过现有的库函

存储空间:变量的大小*线程数,或者可能(sizeof(var)+sizeof(var*))*线程数

有两种实现线程本地存储的基本方法:

  • 使用某种获取当前内核线程信息的系统调用。斯洛

  • 使用一些指针,可能是在处理器寄存器中,内核在每个线程上下文开关处正确设置该指针-与所有其他寄存器同时设置。便宜

  • 在英特尔平台上,变体2通常通过某些段寄存器(我不记得是FS还是GS)实现。GCC和MSVC都支持这一点。因此,访问时间大约与全局变量的访问时间一样快


    这也是可能的,但我还没有在实践中看到,它是通过现有的库函数实现的,比如
    pthread\u getspecific
    。性能将类似于1。或2.,加上库调用开销。记住变量2+库调用开销仍然比内核调用快得多。

    Uli Drepper(glibc的维护者)对它在Linux上如何工作的描述可以在这里找到:

    处理动态加载的模块等的要求使得整个机制有点复杂,这可能部分解释了为什么文档的权重为79页(!)

    内存使用方面,每个每线程变量显然需要它自己的每线程内存(尽管在某些情况下,这可以延迟完成,以便只在第一次访问变量时分配空间),然后还有一些额外的数据结构需要用于偏移表等

    就性能而言,访问TLS变量的额外成本主要围绕检索变量的地址。在x86-64 FS上,GS寄存器用作获取线程id的起点。通常会有一些指针解引用,以及动态加载代码的函数调用(_tls_get_addr)。另外还有一个成本,即创建一个新线程的速度较慢,因为实现需要分配空间,并且可能需要初始化所有TLS变量(如果不是延迟完成的话)


    TLS很容易使一些旧的线程不安全代码模式成为线程安全的(想想errno),但对于从一开始就为多线程世界设计的新代码来说,它很少需要。

    最大的成本是代码的可维护性。我不同意这种很少需要的评论。TLS是一种非常简单、干净、快速的方法,可以通过避免线程中的重复查找来减少线程之间的争用并提高性能。应该注意的是,OS可执行加载程序和动态链接器(用于共享库/DLL)需要对变体2的特定支持。通过段寄存器使TLS工作实际上是一项艰巨的工作。但这是非常值得的,因为使用TLS变量的开销与普通全局变量相比可以忽略不计。