Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
简单基准测试(Java)奇怪的多线程性能_Java_Multithreading_Performance_Benchmarking - Fatal编程技术网

简单基准测试(Java)奇怪的多线程性能

简单基准测试(Java)奇怪的多线程性能,java,multithreading,performance,benchmarking,Java,Multithreading,Performance,Benchmarking,最近,我编写了一个非常简单的代码作为基准,以查看我的机器性能的提高。它只是创建一些线程,并在这些线程之间划分一些旋转数。下面是我用java扩展线程的类: public static class LoopThread extends Thread { int index; long numberOfRound; long numberOfSpins; public LoopThread(int index, long numberOfRound, long num

最近,我编写了一个非常简单的代码作为基准,以查看我的机器性能的提高。它只是创建一些线程,并在这些线程之间划分一些旋转数。下面是我用java扩展线程的类:

public static class LoopThread extends Thread {
    int index;
    long numberOfRound;
    long numberOfSpins;

    public LoopThread(int index, long numberOfRound, long numberOfSpins) {
        this.index = index;
        this.numberOfRound = numberOfRound;
        this.numberOfSpins = numberOfSpins;
    }

    public void run() {
        System.out.println("Thread " + index + " started for " + numberOfRound + " rounds and " + numberOfSpins + " spins");
        for(long i = 0; i < numberOfRound; i++) {
            for(long j = 0; j < numberOfSpins; j++) {

            }
        }
        System.out.println("Thread " + index + " ended");
    }
这一变化使我的代码更具可伸缩性。由于我看不出这一变化导致这种改善的明显原因,我一次又一次地尝试,这里有一些我一直看到的结果:

更改前:

time passed for 8 threads and 1000000 rounds and 800000 spins is 63 seconds
time passed for 9 threads and 1000000 rounds and 800000 spins is 69 seconds
简单更改后:

time passed for 8 threads and 1000000 rounds and 800000 spins is 62 seconds
time passed for 9 threads and 1000000 rounds and 800000 spins is 56 seconds
再一次,我看不出这背后有什么明显的原因,我觉得这很奇怪。你知道为什么会这样吗

谢谢

编辑(启动线程和时间的代码):

publicstaticvoidmain(字符串[]args){
int numberOfThreads=Integer.parseInt(args[0]);
long numberOfRounds=long.parseLong(args[1]);
long numberOfSpins=long.parseLong(args[2]);
long startTime=System.currentTimeMillis();
线程[]线程=新线程[numberOfThreads];
for(int i=0;i
发布启动线程和任务完成时间的代码/方法。当然,请检查我的编辑。谢谢你的机器有超线程吗?你可能只有8个真正的CPU内核,所以你不会看到任何改进,过去8线程简单CPU绑定基准这样。是的,它有超线程,但我们看到几乎16X的改进与类似的C++基准与16个线程。另外,我看到在我提到的变更后,改进了14.5倍左右,之前是变更前的11倍左右。我不知道这个改变是如何产生一个更具可伸缩性的代码的。我真的不想深入到正确答案的细节,但我猜你看到的问题与JIT编译器有关,如果编译器完全优化了这个代码,它将需要0毫秒来运行,因为在循环中实际上什么都没有发生。显然,这并不完全是正在发生的事情,但要真正调查它,您应该使用JMH基准框架并启用调试,以查看JVM在每种情况下生成的机器代码。发布启动线程和任务完成时间的代码/方法。当然,请检查我的编辑。谢谢你的机器有超线程吗?你可能只有8个真正的CPU内核,所以你不会看到任何改进,过去8线程简单CPU绑定基准这样。是的,它有超线程,但我们看到几乎16X的改进与类似的C++基准与16个线程。另外,我看到在我提到的变更后,改进了14.5倍左右,之前是变更前的11倍左右。我不知道这个改变是如何产生一个更具可伸缩性的代码的。我真的不想深入到正确答案的细节,但我猜你看到的问题与JIT编译器有关,如果编译器完全优化了这个代码,它将需要0毫秒来运行,因为在循环中实际上什么都没有发生。显然,这并不完全是正在发生的事情,但要真正研究它,您应该使用JMH基准测试框架并启用调试来查看JVM在每种情况下生成的机器代码。
time passed for 8 threads and 1000000 rounds and 800000 spins is 62 seconds
time passed for 9 threads and 1000000 rounds and 800000 spins is 56 seconds
public static void main(String[] args) {
    int numberOfThreads = Integer.parseInt(args[0]);
    long numberOfRounds = Long.parseLong(args[1]);
    long numberOfSpins = Long.parseLong(args[2]);
    long startTime = System.currentTimeMillis();
    Thread[] threads = new Thread[numberOfThreads];

    for( int i = 0; i < numberOfThreads; i++) {
        threads[i] = new LoopThread(i, numberOfRounds, (long) numberOfSpins/numberOfThreads);
        threads[i].start();
    }

    for(Thread t: threads) {
        try {
            t.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    long endTime = System.currentTimeMillis() - startTime;
    System.out.println("time passed for " + numberOfThreads + " threads and " + numberOfRounds + " rounds and " + numberOfSpins + " spins is " + endTime/1000 + " seconds");
}