gpt4 book ai didi

java - 使用超过 6 个线程时性能会显着下降

转载 作者:行者123 更新时间:2023-12-03 23:14:21 25 4
gpt4 key购买 nike

我正在为类做一个简单的抛硬币实验,涉及在一定数量的线程上抛一定数量的硬币。为了运行我们的加速性能测试,我们使用固定数量的抛硬币(我一直使用十亿)并更改线程数。我们使用具有 8 个内核的 AWS 超高 CPU 实例来运行这些测试。出于某种原因,一旦我使用超过 6 个线程,我就会明显变慢。更糟糕的是,它是不一致的。对于相同数量的线程和翻转,有时我会得到 14 秒,有时是 2 秒。这个不成立。我尝试过使用不同的 JVM(OpenJRE 和 Sun JVM)并尝试一个新实例。下面是我的代码和基准测试结果(以毫秒为单位)。我会喜欢一些帮助。谢谢。

编辑:看起来我解决了它,这在很大程度上要感谢 yadab 和 Bruno Reis 的建议。他们建议使用局部变量来跟踪正面的数量,我认为这可能是一个因素。他们还建议在同一个 JVM session 中运行我的所有测试,这几乎肯定是一个因素。谢谢大家的帮助。

Speedup:
Threads | Flips | Time
1 1000000000 16402 16399 16404
2 1000000000 8218 8216 8217
3 1000000000 5493 5483 5492
4 1000000000 4125 4127 4140
5 1000000000 3306 3304 3311
6 1000000000 2758 2766 2756
7 1000000000 8346 7874 10617
8 1000000000 14370 14414 17831
9 1000000000 14956 14764 15316
10 1000000000 13595 14491 14031
11 1000000000 12642 11188 10625
12 1000000000 10620 10629 10876
13 1000000000 8422 9950 9756
14 1000000000 9284 9546 10194
15 1000000000 8524 4134 8046
16 1000000000 6915 6361 7275

代码:

import java.util.Random;

public class CoinFlip implements Runnable {
private final long iterations; //iterations is the number of times the program will run, numHeads is the number of heads counted
private long numHeads;
public CoinFlip(long iterations) {
this.iterations = iterations;
}

@Override
public void run() {
Random rand = new Random();
numHeads = 0;
for (long i = 0; i < iterations; i++) {
if (rand.nextBoolean()) { //True represents heads, false represents a tails
numHeads++;
}
}
}

public long getHeads() { //numHeads getter
return numHeads;
}

public static void main(String[] args) {
final long numIterations , itersPerThread; //iterations: number of iterations, threads: number of threads to run on, itersPerThread: how many iterations each thread is responsible for
final int threads;
if (args.length != 2) {
System.out.println("Usage: java CoinFlip #threads #iterations");
return;
}
try {
threads = Integer.parseInt(args[0]);
numIterations = Long.parseLong(args[1]);
} catch (NumberFormatException e) {
System.out.println("Usage: java CoinFlip #threads #iterations");
System.out.println("Invalid arguments");
return;
}
itersPerThread = numIterations / ((long)threads); //Might cause rounding errors, but we were told to ignore that
Thread[] threadList = new Thread[threads]; //List of running threads so we can join() them later
CoinFlip[] flipList = new CoinFlip[threads]; //List of our runnables so that we can collect the number of heads later
for (int i = 0; i < threads; i++) { //create each runnable
flipList[i] = new CoinFlip(itersPerThread);
}
long time = System.currentTimeMillis(); //start time
for (int i = 0; i < threads; i++) { //create and start each thread
threadList[i] = new Thread(flipList[i]);
threadList[i].start();
}
for (int i = 0; i < threads; i++) { //wait for all threads to finish
try {
threadList[i].join();
System.out.println("Collected thread " + i);
} catch (InterruptedException e) {
System.out.println("Interrupted");
return;
}
}
time = System.currentTimeMillis() - time; //total running time
long totHeads = 0;
for (CoinFlip t : flipList) { //Collect number of heads from each CoinFlip object
totHeads += t.getHeads();
}

//Print results
System.out.println(totHeads + " heads in " + (numIterations / threads)
* threads + " coin tosses on " + threads + " threads");
System.out.println("Elapsed time: " + time + "ms");
}
}

最佳答案

只要您只执行受 CPU 限制的操作,使用比可用内核更多的线程就毫无意义。相反,额外线程的使用增加了上下文切换和调度的开销。

关于java - 使用超过 6 个线程时性能会显着下降,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9570174/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com