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

时间:2011-12-01 16:35:18

标签: multithreading

我遇到了一个面试问题

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

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

我不明白为什么一个人比另一个人更有效率 如果有人愿意为我澄清这个问题 提前谢谢。

2 个答案:

答案 0 :(得分:3)

将阵列分成两半几乎肯定是要走的路。它几乎永远不会慢,而且可能会快得多。

原因很简单:当您从内存中读取数据时,处理器通常会一次读取整个缓存行。确切的大小因处理器而异,但并不重要(但是,如果你关心的话,64字节就会出现问题) - 关键是它一次读取几个字节的连续块

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

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

答案 1 :(得分:1)

不同之处在于,在半分割的情况下,每个线程从左到右线性访问存储器,从索引0搜索 - > N / 2和N / 2 - >分别为N,它最大化缓存使用率,因为内存的预​​取是在线性提前完成的。

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