我可以通过将变量声明为本地线程来避免缓存一致性检查吗?

吉姆·皮瓦尔斯基(Jim Pivarski)

我正在阅读有关CPU如何在多线程应用程序中保持其缓存一致性的信息。在一个内核的高速缓存中进行写操作会将其标记为脏,并且所有其他内核都必须小心,不要从主内存中读取该段,因为主内存副本不是最新的。

我编写的许多应用程序都actor系统一样工作,其可变性仅限于单个线程上的局部变量。我通常不将它们标记为“本地线程”,除非出于语义上的考虑。

但是,我是否缺少优化机会?是否将变量明确标记为线程局部变量(而不是仅以这种方式使用)是否通知硬件它不必检查一致性,因为该变量即使在原则上也不会对其他线程可见?

编辑:作为表达同一事物的高级方式,我是否应该期望通过使用像Akka这样的正式演员系统而不是仅仅遵循我班上的演员范式来提高性能?正式的参与者系统增加了严格性,跨计算机扩展的能力以及可能的一些开销,但是它是否还有助于降低底层细节,例如让线程跳过对已知为非共享的缓存数据的一致性检查?

它是通过将数据标记为“本地线程”来实现的吗?

彼得·科德斯

只要您避免错误共享,就可以了。即确保一个线程使用静态数据与另一个线程使用静态数据不在同一缓存行中您可以通过检查内存顺序机器清除perf事件来查找

如果发现程序有一些错误的共享,您可以重新排列声明的顺序(因为编译器通常倾向于按照声明的顺序存储内容),或者使用链接器部分对其进行处理以选择如何事物被分组在静态存储中。结构或数组也可以为您提供有关内存布局的保证。

TL; DR:如果两个变量将由不同的线程使用,则避免将两个变量放在同一高速缓存行(通常为64B)中。当然,组的东西在一起在从相同的线程的同时修改。


线程局部变量解决了另一个问题它们使同一个函数根据调用它的线程来访问不同的静态变量。这是传递指针的替代方法。

它们仍然像其他static/全局变量一样存储在内存中您可以确定没有虚假共享,但是有更便宜的方法来避免这种情况。

线程局部变量和“普通”全局变量之间的区别在于它们的寻址方式。不仅仅是通过绝对地址访问它们,它还是与线程本地存储块的偏移量。

在x86上,这是通过segment-override前缀完成的。例如,mov rax, QWORD PTR fs:0x28从线程本地存储块内部的字节0x28加载(因为每个线程的fs段寄存器都加载了其自己的TLS块的偏移量)。

因此,TLS不是免费的。如果您不需要它,请不要使用它。但是,它比传递指针便宜。


没有办法让硬件跳过缓存一致性检查,因为硬件没有任何TLS概念。只是存储和加载到内存或从内存加载,以及ISA提供的订购保证由于TLS只是获得相同功能以便为不同的调用者使用不同地址的技巧,因此实现TLS的软件错误可能导致存储到相同地址。硬件不允许错误的软件以这种方式破坏其缓存一致性,因为它有可能破坏特权分离。

在弱排序的体系结构上,memory_order_consume(从理论上来说)是一种安排线程间数据依赖关系的方法,以便其他线程仅需等待对共享数据的写操作,而不必对线程私有数据进行写操作。

但是,这对于编译器难以安全可靠地正确执行是太难了,因此它们当前将mo_consume实现为更强大的mo_acquire。不久前我写了一个非常漫长而漫不经心的答案,其中有一堆指向内存排序内容的链接,并提到了C ++ 11 memory_order_consume。

标准化非常困难,因为不同的体系结构对哪些操作带有依赖项具有不同的规则我假设某些代码库具有一些利用依赖项排序的手写asm。AFAIK,手写asm是利用依赖排序的唯一方法,可避免在弱排序的ISA上使用内存屏障指令。(例如,在生产者-消费者模型中,或在不仅仅需要无序原子存储的无锁算法中。)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

我应该使用Rails来保持一致性吗?(用于ETL项目)

来自分类Dev

线程内一致性

来自分类Dev

我可以牺牲一致性来允许并发“插入或更新”以及使用SQL Server对单个表进行读取访问吗?

来自分类Dev

我可以牺牲一致性来允许并发“插入或更新”以及使用SQL Server对单个表进行读取访问吗?

来自分类Dev

如何使一致性完全分布(没有本地缓存)

来自分类Dev

如果我编写了一段代码,其中每个线程都修改了数组的完全不同的部分,那将保持高速缓存的一致性吗?

来自分类Dev

CPU何时可以忽略LOCK前缀并使用高速缓存一致性?

来自分类Dev

缓存一致性中的MESI协议

来自分类Dev

Akka.Net和缓存一致性

来自分类Dev

一致性:事务缓存中的分页

来自分类Dev

计算一致性缓存高单位

来自分类Dev

如何从数据帧中重复注册的不同ID检查特定变量的一致性

来自分类Dev

线程数和时间结果的一致性

来自分类Dev

如果我们使用内存防护来增强一致性,那么“线程颠簸”怎么会发生?

来自分类Dev

WAIT命令可以在Redis中提供强一致性吗?

来自分类Dev

Swift的相等协议一致性检查

来自分类Dev

如何启用Modelica单元一致性检查

来自分类Dev

如何检查CSV列的一致性?

来自分类Dev

如何使用autoconf检查POSIX一致性

来自分类Dev

Swift的等价协议一致性检查

来自分类Dev

有没有一种方法可以衡量缓存一致性未命中

来自分类Dev

我们可以将JPA静态元模型类的成员变量声明为final吗?

来自分类Dev

RenderScript本地线程同步可以吗?

来自分类Dev

索引节点编号序列如何工作?我可以期望不同计算机上相同安装的一致性吗?

来自分类Dev

缓存一致性(特别是物理标记缓存的情况)

来自分类Dev

我可以通过指定结构或类来避免前向声明吗

来自分类Dev

将一致性更新为12.1.3之后,NamedCache.putall中的一致性异常

来自分类Dev

Java易失性和缓存一致性

来自分类Dev

缓存一致性协议如何强制执行原子性?

Related 相关文章

  1. 1

    我应该使用Rails来保持一致性吗?(用于ETL项目)

  2. 2

    线程内一致性

  3. 3

    我可以牺牲一致性来允许并发“插入或更新”以及使用SQL Server对单个表进行读取访问吗?

  4. 4

    我可以牺牲一致性来允许并发“插入或更新”以及使用SQL Server对单个表进行读取访问吗?

  5. 5

    如何使一致性完全分布(没有本地缓存)

  6. 6

    如果我编写了一段代码,其中每个线程都修改了数组的完全不同的部分,那将保持高速缓存的一致性吗?

  7. 7

    CPU何时可以忽略LOCK前缀并使用高速缓存一致性?

  8. 8

    缓存一致性中的MESI协议

  9. 9

    Akka.Net和缓存一致性

  10. 10

    一致性:事务缓存中的分页

  11. 11

    计算一致性缓存高单位

  12. 12

    如何从数据帧中重复注册的不同ID检查特定变量的一致性

  13. 13

    线程数和时间结果的一致性

  14. 14

    如果我们使用内存防护来增强一致性,那么“线程颠簸”怎么会发生?

  15. 15

    WAIT命令可以在Redis中提供强一致性吗?

  16. 16

    Swift的相等协议一致性检查

  17. 17

    如何启用Modelica单元一致性检查

  18. 18

    如何检查CSV列的一致性?

  19. 19

    如何使用autoconf检查POSIX一致性

  20. 20

    Swift的等价协议一致性检查

  21. 21

    有没有一种方法可以衡量缓存一致性未命中

  22. 22

    我们可以将JPA静态元模型类的成员变量声明为final吗?

  23. 23

    RenderScript本地线程同步可以吗?

  24. 24

    索引节点编号序列如何工作?我可以期望不同计算机上相同安装的一致性吗?

  25. 25

    缓存一致性(特别是物理标记缓存的情况)

  26. 26

    我可以通过指定结构或类来避免前向声明吗

  27. 27

    将一致性更新为12.1.3之后,NamedCache.putall中的一致性异常

  28. 28

    Java易失性和缓存一致性

  29. 29

    缓存一致性协议如何强制执行原子性?

热门标签

归档