gcc的线程本地存储可以跨线程共享缓存行吗?

时间:2016-02-07 19:03:16

标签: linux gcc cpu-cache

如果使用__thread声明变量或常量大小的数组,则后备虚拟地址范围是否可以跨线程共享高速缓存行? (例如,如果线程本地整数的两个副本落在同一个高速缓存行上,性能将因高速缓存行反弹而受到影响。)答案是否依赖于gcc / Linux版本和硬件架构?

1 个答案:

答案 0 :(得分:2)

Ultrich Drepper是臭名昭着的专家,前glibc维护者,“没有在正常的数据段中分配;相反,每个线程都有自己独立的区域来存储这些变量。变量可以有静态初始化器。所有线程本地变量可由所有其他线程寻址,但除非线程将指向线程局部变量的指针传递给其他线程,否则其他线程无法找到该变量。由于变量是线程局部的,因此错误共享是不是问题 - 除非程序人为地产生问题。“

如果你学习,Memory part 6: More things programmers can do线程局部变量,如果指针被传递,可能正在访问同一个缓存行。

要避免此问题,请不要传递相关地址。描述了将频繁的rw变量分组在一起以在结构中共享缓存行的特定技术,使用填充来避免在不使用TLS时写入同一缓存行的多个线程,只要__thread变量指针不被其他线程使用,高速缓存行反弹应该避免。

希望链接器实现者知道CPU架构,你不能选择虚拟和安全的位置。物理内存地址空间是分配的乘法线程本地存储,应该安全地假设它们加上CPU设计者在避免由于错误冲突导致的性能问题方面做了合理的工作。在单独的进程之间偶然发生同样的问题,如果缓存关联性反弹是一个常见的问题,那就永远不会发现线程。