H5W3
当前位置:H5W3 > java > 正文

Java多线程无法在更多内核上更快地运行

我只是在4核计算机上运行一些多线程代码,希望它比在单核计算机上更快。思路是这样的:我得到了固定数量的线程(在我的情况下,每个内核一个线程)。每个线程执行以下形式的Runnable:

private static int[] data; // data shared across all threads
public void run() {
int i = 0;
while (i++ < 5000) {
// do some work
for (int j = 0; j < 10000 / numberOfThreads) {
// each thread performs calculations and reads from and
// writes to a different part of the data array
}
// wait for the other threads
barrier.await();
}
}

在四核计算机上,此代码在4个线程上的性能比在1个线程上的性能差。即使有了CyclicBarrier的开销,我也会认为该代码的执行速度至少要快2倍。为什么运行速度较慢?

编辑:这是我尝试的繁忙等待实现。不幸的是,这使程序在更多内核上的运行速度变慢(也在另一个问题here中进行了讨论):

public void run() {
// do work
synchronized (this) {
if (atomicInt.decrementAndGet() == 0) {
atomicInt.set(numberOfOperations);
for (int i = 0; i < threads.length; i++)
threads[i].interrupt();
}
}
while (!Thread.interrupted()) {}
}

最佳答案

添加更多线程并不一定要保证提高性能。使用其他线程会导致性能下降的原因有很多:

  • 粗粒度锁定可能会过度序列化执行-即,锁定可能导致一次仅运行一个线程。您获得了多个线程的所有开销,但没有任何好处。尝试减少持有锁的时间。
  • 这同样适用于过于频繁的障碍和其他同步结构。如果内部j循环快速完成,您可能会花费大部分时间在障碍中。尝试在同步点之间做更多的工作。
  • 如果您的代码运行速度太快,则可能没有时间将线程迁移到其他CPU内核。除非您创建许多生命周期很短的线程,否则通常这不是问题。使用线程池或简单地给每个线程更多的工作可以有所帮助。如果每个线程的运行时间都超过一秒左右,则这不太可能成为问题。
  • 如果您的线程正在处理许多共享的读/写数据,则缓存行跳动可能会降低性能。就是说,尽管这通常会导致性能下降,但仅此一项就不会导致性能比单线程情况差。尝试确保每个线程写入的数据与其他线程的数据之间的间隔为高速缓存行的大小(通常为64字节左右)。特别是,不要像[thread A, B, C, D, A, B, C, D ...]

那样布置输出数组

由于您尚未显示代码,因此我在这里无法真正详细地说明。

本文地址:H5W3 » Java多线程无法在更多内核上更快地运行

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址