7

我在 Visual C++ 文档中读到,多个线程从同一个对象中读取是安全的。

我的问题是:多核 X86-64 CPU 如何处理这个问题?

假设您有一个 1 MB 的内存块。不同的线程真的能够同时读取完全相同的数据,还是核心一次读取一个单词而一次只允许一个核心读取一个特定的单词?

4

2 回答 2

12

如果您的 1MB 块中确实没有写入,那么是的,每个内核都可以毫无问题地从自己的缓存行读取,因为没有写入被提交,因此不会出现缓存一致性问题。

在多核架构中,基本上每个核心都有一个缓存和一个“缓存一致性协议”,它使某些没有最新信息的核心上的缓存无效。我认为大多数处理器都实现了MOESI 协议以实现缓存一致性。

缓存一致性是一个已被广泛讨论的复杂主题(我特别喜欢 Joe Duffy 的一些文章herehere)。尽管如此,讨论仍围绕代码可能的性能损失展开,虽然显然是无锁的,但由于缓存一致性协议启动以保持处理器缓存之间的一致性,可能会减慢速度,但是,只要没有写入,就根本没有保持一致性,因此不会损失性能。

只是为了澄清,正如评论中所说,由于 x86 和 x64 架构实现了一个在内核之间共享的单一总线,因此不能同时访问 RAM,而SMP保证了访问主存储器的公平性。尽管如此,每个核心缓存都隐藏了这种情况,这允许每个核心拥有自己的数据副本。对于 1MB 的数据,在核心更新其缓存时可能会发生一些争用,但这可以忽略不计。

一些有用的链接:

于 2009-11-03T10:40:19.140 回答
8

不仅允许不同的内核从同一块内存中读取,还允许它们同时写入。如果它“安全”与否,那是完全不同的故事。您需要在代码中实现某种保护(通常使用信号量或它们的衍生物完成),以防止多个内核以您不明确允许的方式争夺同一内存块。

关于内核一次读取的内存大小,通常是一个寄存器的值,32 位 cpu 上为 32 位,64 位 cpu 上为 64 位,依此类推。甚至流式传输也是由 dword 完成的(例如,查看 memcpy)。

关于并发多核的实际情况,每个核使用单个总线来读取和写入内存,因此访问任何资源(内存、外部设备、浮点处理单元)是一次一个请求,一次一个核. 然而,核心内部的实际处理是完全并发的。DMA 传输也不会阻塞总线,并发传输会排队并一次处理一个(我相信,这不是 100% 确定的)。

编辑:只是为了澄清,与这里的其他回复不同,我只在谈论无缓存场景。当然,如果内存被缓存,只读访问是完全并发的。

于 2009-11-03T10:42:15.973 回答