为什么比核心更多的线程更快?

lau*_*cer 7 performance multithreading pthreads

我在多线程版本中实现了一个PageRank版本.我在4核Q6600上运行它.当我运行它设置为创建4个线程时,我得到:

real    6.968s
user   26.020s
sys     0.050s
Run Code Online (Sandbox Code Playgroud)

当我运行128个线程时,我得到:

real    0.545s
user    1.330s
sys     0.040s
Run Code Online (Sandbox Code Playgroud)

这对我来说毫无意义.基本算法是sum-reduce:

  1. 所有线程总和输入的子集;
  2. 同步;
  3. 然后每个线程累积来自其他线程的部分结果;
  4. 主线程将所有线程的中间值相加,然后确定是否继续.

分析没有帮助.我不确定哪些数据有助于理解我的代码 - 请问问.

这让我很困惑.

Ant*_*ams 11

故意创建比处理器更多的线程是用于利用"备用周期"的标准技术,其中线程被阻塞等待某事,无论是I/O,互斥体还是其他东西,通过为处理器提供一些其他有用的工作来做.

如果您的线程正在进行I/O,那么这是加速的有力竞争者:当每个线程阻塞等待I/O时,处理器可以运行其他线程,直到它们也阻塞I/O,希望通过它第一个线程的数据准备好的时间,等等.

加速的另一个可能原因是您的线程正在经历错误共享.如果有两个线程在同一个高速缓存行上将数据写入不同的值(例如,数组的相邻元素),那么这将阻塞CPU,同时来回传输高速缓存行.通过添加更多线程,可以降低它们对相邻元素进行操作的可能性,从而减少错误共享的可能性.您可以通过向数据元素添加额外的填充来轻松地测试它,因此它们的大小至少为64字节(典型的缓存行大小).如果您的4线程代码加速,这就是问题所在.

  • 关于虚假分享的猜测非常好.但考虑到运行时间的巨大差异,我宁愿怀疑工作分区逻辑中的竞争条件错误,因此具有许多线程的版本"忘记"某些作业并且不会像另一个那样做. (3认同)

Ric*_*ell 7

你可能有空闲的CPU周期,而线程阻塞一些资源,如内存.其他线程可以使用这些CPU周期.我要看的数据是...... 4线程版本是否显示每个核心的100%利用率?如果没有,你就找到了你的备用CPU周期.