内存访问 vs. 内存复制

6

我正在用C++编写应用程序,需要从许多线程中反复读取同一内存的只读数据。我的问题是,从性能角度来看,是将内存复制到每个线程中还是给所有线程相同的指针并让它们都访问同一内存更好。

谢谢!


1
显而易见的问题是:在读取时,这个内存是恒定的还是会发生变化? - Matthieu M.
1
@Mysticial,人们希望所有的架构都能有效地处理多次读取的数据,而不仅仅是NUMA系统。 - edA-qa mort-ora-y
@AmigableClarkKant:对于你的答案所假设的内容,最好只针对你的答案进行限制(在答案开始时声明你的假设更好,这样方便阅读)。然而,在这里我并不关心你的假设;问题是针对OP的(不是你),因为我们需要OP来澄清问题。 - Matthieu M.
我认为重点在于,在NUMA系统上,每个节点拥有本地副本可能会带来好处,而如果内存访问是均匀的,则可能没有多个副本的好处。 - Mike Seymour
1
@MikeSeymour,我只是想表明,尽管内存架构很重要,但它是否为NUMA可能并不重要。 SMP / NUMA(以及可能的其他架构)倾向于在当前正在使用的数据上使用本地缓存。 - edA-qa mort-ora-y
2个回答

6

根据你提供的目标系统等少量信息,没有明确的答案,但在普通PC上,最快的方法很可能是不复制。

复制可能会变慢的原因之一是,如果数据区域很大,可能会导致缓存未命中。普通PC会在线程之间非常有效地缓存只读访问同一数据区域的数据,即使这些线程恰好运行在不同的核心上也是如此。

英特尔为其缓存方法明确列出的一个优点是{{link1:“允许运行在共享缓存的分离核心上的线程之间更多的数据共享机会”}}。也就是说,他们鼓励不必显式编程缓存数据的实践,CPU将为您完成它。


1

由于您特别提到了许多线程,我假设您至少拥有一个多插槽系统。通常,内存银行与处理器插座相关联。也就是说,一个处理器“最接近”自己的内存银行,并且需要与其他处理器的内存控制器通信以访问其他银行上的数据。(这里的处理器指的是插座中的物理部件)

当您分配数据时,通常会使用先写策略来确定数据将分配到哪些内存银行,这意味着它可以比其他处理器更快地访问它。

因此,对于多个处理器(而不仅仅是多个核心),为每个处理器分配一个副本应该会有性能提升。请确保使用每个处理器/线程进行分配/复制数据,而不是从主线程进行分配/复制(以利用先写策略)。此外,您需要确保线程不会在处理器之间迁移,因为那样您可能会失去与内存的紧密连接。

我不确定在单个处理器上为每个线程复制数据会如何影响性能,但我猜想不复制可能会提高共享在核心之间共享的高级缓存内容的能力。

无论如何,基于实际测量进行基准测试和决策。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接