我的 Java 应用程序基本上是这样做的:
- 从文件中读取 nThread 缓冲区(1 mb 字节数组)
- 创建处理缓冲区的 nThread 线程
- 等待线程处理数据
- 将处理后的数据写入另一个文件
它是应该为每个内核实现理论上 100% 速度提升的应用程序之一,但相反,处理信息的线程越多,它变得越慢!
例子:
- 1 个线程:4800 毫秒
- 2 个线程:10200 毫秒
- 3 个线程:13400 毫秒
- 4 个线程:18560 毫秒
- 等等
我的 Java 应用程序基本上是这样做的:
它是应该为每个内核实现理论上 100% 速度提升的应用程序之一,但相反,处理信息的线程越多,它变得越慢!
例子:
在添加线程时获得这种性能意味着您做错了什么。通常添加线程不会提供任何速度改进,有时可能会有点惩罚你,但添加另一个线程并使程序运行时间加倍是非常不寻常的。
这里有一些事情需要调查:
ExecutorService
而不是自己管理自己的线程。这通常会删除很多用户代码和相关的错误。见Executors.newFixedThreadPool(numThread)
。new Thread(...).start()
而不是run()
直接打电话。join()
之前打电话吗?您应该将start()
所有线程分派给它们,然后join()
在最后对它们进行调度。如果您在问题中向我们展示您的一些线程代码,我们可以提供更多帮助。
未经充分优化的代码通常会自行耗尽整个内存带宽。在多核处理器上使用相同的未优化代码添加另一个线程,它们将在它们之间分配带宽,此外,还会经常相互碰撞,进一步减慢速度。
格雷说:“......将程序运行时间加倍是非常不寻常的。” 我不同意。这通常是在您开始优化内存访问之前在 C 代码中发生的情况。我想说从一开始就没有看到放缓是非常不寻常的。
我不知道 Java 是否可以进行采样,但这是一个显而易见的起点。