我正在试验一些多线程结构,但不知何故,多线程似乎并不比单线程快。我将其缩小为一个非常简单的测试,其中包含一个嵌套循环 (1000x1000),系统只在其中计算。
下面我贴出了单线程和多线程的代码以及它们是如何执行的。
结果是单线程完成循环大约需要110 ms,而两个线程也需要大约112 ms。
我不认为问题是多线程的开销。如果我只将两个 Runnable 中的一个提交给 ThreadPoolExecutor,它的执行时间是单线程的一半,这是有道理的。但是添加第二个 Runnable 会使它慢 10 倍。两个 3.00Ghz 内核都在 100% 运行。
我认为这可能是特定于 pc 的,因为其他人的 pc 在多线程上显示了双倍速度的结果。但是,我能做些什么呢?我有一个 Intel Pentium 4 3.00GHz(2 个 CPU)和 Java jre6。
测试代码:
// Single thread:
long start = System.nanoTime(); // Start timer
final int[] i = new int[1]; // This is to keep the test fair (see below)
int i = 0;
for(int x=0; x<10000; x++)
{
for(int y=0; y<10000; y++)
{
i++; // Just counting...
}
}
int i0[0] = i;
long end = System.nanoTime(); // Stop timer
此代码的执行时间约为 110 毫秒。
// Two threads:
start = System.nanoTime(); // Start timer
// Two of the same kind of variables to count with as in the single thread.
final int[] i1 = new int [1];
final int[] i2 = new int [1];
// First partial task (0-5000)
Thread t1 = new Thread() {
@Override
public void run()
{
int i = 0;
for(int x=0; x<5000; x++)
for(int y=0; y<10000; y++)
i++;
i1[0] = i;
}
};
// Second partial task (5000-10000)
Thread t2 = new Thread() {
@Override
public void run()
{
int i = 0;
for(int x=5000; x<10000; x++)
for(int y=0; y<10000; y++)
i++;
int i2[0] = i;
}
};
// Start threads
t1.start();
t2.start();
// Wait for completion
try{
t1.join();
t2.join();
}catch(Exception e){
e.printStackTrace();
}
end = System.nanoTime(); // Stop timer
此代码的执行时间约为 112 毫秒。
编辑:我将 Runnables 更改为 Threads 并去掉了 ExecutorService(为简化问题)。
编辑:尝试了一些建议
最佳答案
您绝对不想继续轮询 Thread.isAlive()
- 这无缘无故地消耗了大量 CPU 周期。请改用 Thread.join()
。
此外,让线程直接递增结果数组、缓存行和所有内容可能不是一个好主意。更新局部变量,并在计算完成后进行单个存储。
编辑:
完全忽略了您使用的是 Pentium 4。据我所知,P4 没有多核版本 - 为了给人一种多核的错觉,它有 Hyper-Threading : 两个逻辑核心共享一个物理核心的执行单元。如果您的线程依赖于相同的执行单元,您的性能将与(或更差!)单线程性能。例如,您需要在一个线程中进行浮点计算,在另一个线程中进行整数计算,以获得性能改进。
P4 HT 实现受到了很多批评,较新的实现(最近的 core2)应该会更好。
关于java - 多线程不比单线程快(简单循环测试),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3820647/