Multithreading 效率问题-在并行线程上搜索数组

Multithreading 效率问题-在并行线程上搜索数组,multithreading,Multithreading,我遇到一个面试问题,问 使用2个并行线程在数组中搜索值时 哪种方法更有效 (1) 在不同的线程上读取数组的每一半(将其拆分为两半) (2) 读取奇数和偶数位置的数组(读取奇数位置的线程 和读取数组中偶数位置的一个) 我不明白为什么一个比另一个更有效 如果有人能帮我澄清,请通知我 提前感谢。将阵列一分为二几乎肯定是正确的做法。它几乎永远不会变慢,而且可能会大大加快 原因很简单:当您从内存中读取数据时,处理器通常一次读取整个缓存线。处理器之间的确切大小各不相同,但这并不重要(不过,如果你介意的话,大

我遇到一个面试问题,问

使用2个并行线程在数组中搜索值时 哪种方法更有效

(1) 在不同的线程上读取数组的每一半(将其拆分为两半) (2) 读取奇数和偶数位置的数组(读取奇数位置的线程
和读取数组中偶数位置的一个)

我不明白为什么一个比另一个更有效 如果有人能帮我澄清,请通知我
提前感谢。

将阵列一分为二几乎肯定是正确的做法。它几乎永远不会变慢,而且可能会大大加快

原因很简单:当您从内存中读取数据时,处理器通常一次读取整个缓存线。处理器之间的确切大小各不相同,但这并不重要(不过,如果你介意的话,大概是64字节)——关键是它一次读取几个字节的连续块

这意味着对于奇数/偶数版本,运行两个线程的两个处理器都必须读取所有数据。通过将数据一分为二,每个核心将只读取一半的数据。如果拆分不在缓存线边界上,则每个拆分都会额外读取一点数据(它需要的数据将四舍五入到缓存线的大小)。平均而言,这将在每个需要读取的内容上添加半条缓存线


如果所涉及的“处理器”实际上是同一处理器上的两个内核,那么很可能这两种方式都不会产生太大的差异。在这种情况下,瓶颈通常是将数据从主存读取到最低级别的处理器缓存中。即使只有一个线程,您也(可能)能够以从内存读取数据的速度搜索数据,而添加更多线程(无论您如何安排它们对数据的使用)不会有多大改善(如果有的话)。

不同之处在于,在半拆分的情况下,每个线程从左到右线性访问内存,分别从索引0->N/2和N/2->N进行搜索,这将最大限度地提高缓存使用率,因为内存的预取是线性提前完成的


在第二种情况下(偶数-奇数),缓存性能会更差,这不仅是因为您将预取未使用的项(线程0获取元素0、1等,但仅使用其中的一半),而且还因为缓存乒乓效应(在写入的情况下,但在您的示例中没有这样做).

这可能与缓存性能有关。您的意思是因为两个线程都将从同一起始地址读取,所以在读取阵列的后半部分时,缓存不会读取更多冗余数据?是的。这听起来相当正确。我上面的评论听起来有点愚蠢,因为两个处理器都会以任何方式读取适合缓存线的数据量。如果某些数据对进程来说是冗余的,这并不重要。