【问题标题】:java performance on two different servers两台不同服务器上的java性能
【发布时间】:2011-07-22 02:36:10
【问题描述】:

不确定这个问题应该是在这里还是在 serverfault 中,但它与 java 相关,所以这里是:

我有两台服务器,技术非常相似:

  • server1 是 Oracle/Sun x86,具有双 x5670 CPU (2.93 GHz)(每个 4 核),12GB RAM。
  • server2 是 Dell R610,配备双 x5680 CPU (3.3 GHz)(每个 6 核),16GB RAM。

两者都运行 Solaris x86,配置完全相同。

两者都启用了涡轮增压,并且没有超线程。

因此,server2 应该比 server1 稍快。

我正在两个平台上运行以下简短的测试程序。

import java.io.*;

public class TestProgram {

public static void main(String[] args) {
    new TestProgram ();
}

public TestProgram () {
    try {
        PrintWriter writer  = new PrintWriter(new FileOutputStream("perfs.txt", true), true);

        for (int i = 0; i < 10000; i++) {
            long t1 = System.nanoTime();
            System.out.println("0123456789qwertyuiop0123456789qwertyuiop0123456789qwertyuiop0123456789qwertyuiop");
            long t2 = System.nanoTime();

            writer.println((t2-t1));

            //try {
            //  Thread.sleep(1);
            //}
            //catch(Exception e) {
            //  System.out.println("thread sleep exception");
            //}
        }
    }
    catch(Exception e) {
        e.printStackTrace(System.out);
    }
}
}

我打开 perfs.txt 并对结果进行平均,我得到:

  • server1:平均 = 1664,修剪 10% = 1615
  • server2:平均 = 1510,修剪 10% = 1429

这是一个有点预期的结果(server2 perfs > server1 perfs)。

现在,我取消注释“Thread.sleep(1)”部分并再次测试,现在的结果是:

  • server1:平均 = 27598,修剪 10% = 26583
  • server2:平均值 = 52320,修剪 10% = 39359

这一次 server2 性能

这对我来说没有任何意义......

显然,我正在寻找一种在第二种情况下提高 server2 性能的方法。一定有某种不同的配置,我不知道是哪一种。 操作系统相同,java版本相同。

它可以与核心数量相关联吗? 也许这是BIOS设置?尽管 BIOS 不同(AMI 与 Dell),但设置看起来非常相似。

我会尽快更新戴尔的 BIOS 并重新测试,但如果有任何见解,我将不胜感激......

谢谢

【问题讨论】:

  • 也许我理解错了,但是鉴于您发布的代码,取消注释 Thread.sleep() 调用甚至会影响时间是没有任何意义的。只有在 Thread.sleep() 之后 花费 t2 时间才有意义。
  • 可能是磁盘缓存不同?
  • @davmac :你没有误解,你是对的,这没有任何意义,但仍然是我得到的结果,这就是我发布的原因。跨度>
  • @isobar :我可以检查一下,但是我忘了提到虽然我使用的是“System.out.println”,但在进行任何类型的计算时都会获得相同的结果模式,甚至不是包括 I/O(我尝试了一系列的数学计算,相同的模式)
  • 您真正想测量什么?您的程序甚至没有接近服务器性能的有效比较 - System.out.println 不完全是基准标准。为什么不使用开箱即用的基准测试之一?我喜欢 VolanoMark (volano.com/benchmarks.html),因为它的设置是毫无意义的,并且为 (IME) 提供了对典型 Web 应用程序的服务器“牛肉”的非常合理的比较。

标签: java performance settings cpu


【解决方案1】:

我会尝试不同的测试程序,尝试运行类似这样的东西。

public class Timer implements Runnable
{
    public void startTimer()
    {
        time = 0;
        running = true;
        thread = new Thread(this);
        thread.start();
    }

    public int stopTimer()
    {
        running = false;
        return time;
    }

    public void run()
    {
        try
        {
            while(running)
            { 
                Thread.sleep(1);
                time++;
            }
        }catch(Exception e){e.printStackTrace();}
    }

    private int time;
    private Thread thread;
    private boolean running;
}

这是计时器,现在主要是:

public class Main
{
    public static void main(String args[])
    {
        Timer timer = new Timer();
        timer.startTimer();
        for(int x=0;x<1000;x++)
            System.out.println("Testing!!");
        System.out.println("\n\nTime Taken: "+timer.stopTimer());
     }
}

我认为这是测试系统是否真正运行得更快的好方法。试试这个,让我知道结果如何。

【讨论】:

  • 这个测试没有复制我正在尝试改进的生产程序,但我仍然运行它,并且得到了“预期”的结果:server2 比 server1 快。我仍然无法解释为什么我的程序在 serve2 上运行速度较慢。
【解决方案2】:

好的,我有一个理论:Thread.sleep() 阻止热点编译器启动。因为你有一个睡眠,它假设循环不是“热”的,即它并不重要循环中的代码效率如何(因为毕竟,你睡觉的唯一目的可能是减慢速度)。

因此,您在循环中添加了一个 Thread.sleep(),循环中的其他内容也运行得更慢。

我想知道,如果您在循环内有一个循环并测量内部循环的性能,是否会有所不同? (并且只有 Thread.sleep() 在外循环中)。在这种情况下,编译器可能会优化内部循环(如果有足够的迭代次数)。

(提出一个问题:如果这段代码是从生产代码中提取的测试用例,为什么生产代码会休眠?)

【讨论】:

  • 有趣。但是,为什么编译器在运行相同操作系统版本和相同 java 版本的两个系统上会表现不同?行为应该是相同的,不是吗? VM /编译器不与硬件本身交互,而是与操作系统交互,对吗?即使在这种情况下,硬件在 server2 上仍然“更快”。代码在生产中并不完全相同,基本上都有并发线程。我开始通过在它旁边运行其他线程以这种方式对其进行测试,然后慢慢地继续隔离问题,并达到了这一点。
【解决方案3】:

我实际上更新了 DELL R610 上的 BIOS,并确保调整所有 BIOS CPU 参数以获得最佳的低延迟性能(无超线程等...)。 它解决了它。有和没有 Thread.sleep 的性能是有道理的,R610 在这两种情况下的整体性能都比 Sun 好得多。 原来的 BIOS 似乎没有正确或完全使用 nehalem 功能(而 Sun 做到了)。

【讨论】:

    【解决方案4】:

    您正在测试控制台更新的速度。这完全取决于操作系统和窗口。如果您在 IDE 中运行它,它将比在 xterm 中运行慢得多。即使您使用哪种字体以及您的窗口有多大,也会对性能产生很大影响。如果在运行测试时关闭窗口,这将提高性能。


    这是我将如何运行相同的测试。该测试是独立的,可以进行您需要的分析。

    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.Arrays;
    
    public class TestProgram {
        public static void main(String... args) throws IOException {
            File file = new File("out.txt");
            file.deleteOnExit();
            PrintWriter out = new PrintWriter(new FileWriter(file), true);
    
            int runs = 100000;
            long[] times = new long[runs];
            for (int i = -10000; i < runs; i++) {
                long t1 = System.nanoTime();
                out.println("0123456789qwertyuiop0123456789qwertyuiop0123456789qwertyuiop0123456789qwertyuiop");
                long t2 = System.nanoTime();
                if (i >= 0)
                    times[i] = t2 - t1;
            }
            out.close();
            Arrays.sort(times);
            System.out.printf("Median time was %,d ns, the 90%%tile was %,d ns%n", times[times.length / 2], times[times.length * 9 / 10]);
        }
    }
    

    在 2.6 GHz Xeon WIndows Vista 机器上打印

    Median time was 3,213 ns, the 90%tile was 3,981 ns
    

    【讨论】:

    • 不,实际上我正在将标准输出重定向到文件,因此不涉及这些。另外,如上所述,如果 System.out.println 被替换为非 IO 代码,例如多个数学计算,则结果模式是相同的。
    • 您的测试确实不错,我得到的结果是预期的:2.93GHz 上为 2000 ns,3.3GHz 上为 1860 ns。但是,我的问题是要了解为什么我在原始测试用例中没有使用“Thread.sleep()”行(对应于生产)得到相同的模式,这是我最初的问题。唯一的区别是核心数量(2*4 与 2*6)......
    猜你喜欢
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 2016-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-15
    相关资源
    最近更新 更多