多线程和内存

问题描述 投票:6回答:2

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

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

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

c++ multithreading cpu x86-64
2个回答
5
投票

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

[关于一次内核读取的内存大小,通常是寄存器的价值,一个32位cpu上为32位,一个64位cpu上为64位,依此类推。甚至流都是一个字一个字地完成的(例如,查看memcpy)。

关于并发多个内核的实际情况,每个内核使用一条总线来读写内存,因此一次访问任何资源(内存,外部设备,浮点处理单元)都是一个请求,一个内核在一个时间。但是,内核内部的实际处理是完全并发的。 DMA传输也不会阻塞总线,并发传输一次会排队并处理一次(我相信对此不是100%肯定的)。

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


11
投票

如果您的1MB块中确实没有任何写操作,那么,是的,每个内核都可以从自己的高速缓存行中读取数据,因为没有提交任何写操作,因此不会出现高速缓存一致性问题。

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

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

仅在注释中阐明,不能同时访问RAM,因为x86和x64体系结构实现了单个总线,该总线在内核之间共享,SMP保证公平地访问主内存。但是,每个内核高速缓存都隐藏了这种情况,它允许每个内核拥有自己的数据副本。对于1MB的数据,在核心更新其缓存时可能会引起某些争用,但这可以忽略不计。

一些有用的链接:

© www.soinside.com 2019 - 2024. All rights reserved.