Domanda

Ho un test molto semplice unità che solo assegna un sacco di stringhe:

public class AllocationSpeedTest extends TestCase {

    public void testAllocation() throws Exception {

        for (int i = 0; i < 1000; i++) {
            long startTime = System.currentTimeMillis();
            String a = "dummy";
            for (int j = 0; j < 1000; j++) {
                a += "allocation driven";
            }
            System.out.println(i + ": " + (System.currentTimeMillis() - startTime) + "ms " + a.length());
        }

    }

}

Sul mio PC Windows (Intel Core Duo, 2.2GHz, 2GB) viene stampato in media:

...
71: 47ms 17005
72: 47ms 17005
73: 46ms 17005
74: 47ms 17005
75: 47ms 17005
76: 47ms 17005
77: 47ms 17005
78: 47ms 17005
79: 47ms 17005
80: 62ms 17005
81: 47ms 17005
...

Il SunOS (5,10 Generic_138888-03 sun4v SPARC SUNW, SPARC-Enterprise-T5120):

...
786: 227ms 17005
787: 294ms 17005
788: 300ms 17005
789: 224ms 17005
790: 260ms 17005
791: 242ms 17005
792: 263ms 17005
793: 287ms 17005
794: 219ms 17005
795: 279ms 17005
796: 278ms 17005
797: 231ms 17005
798: 291ms 17005
799: 246ms 17005
800: 327ms 17005
...

versione JDK 1.4.2_18 è su entrambe le macchine. parametri JVM sono gli stessi e sono:

–server –Xmx256m –Xms256m

Qualcuno può spiegare perché super-server Sun è più lento?

( http://www.sun.com/servers/coolthreads/ T5120 / performance.xml )

È stato utile?

Soluzione

La CPU è effettivamente più lenta su SPARC (1.2Ghz) e come risposta da uno dei del Sole ingegneri T2 è Di solito 3 volte più lento per applicazioni single-threaded che moderni processori Intel. Anche se, ha anche affermato che in un ambiente multi-threaded SPARC dovrebbe essere più veloce.

Ho fatto un test multi-thread utilizzando la libreria GroboUtils e testato entrambi assegnazioni (attraverso concatenazioni) e calcoli semplici (a + = j * j) per testare processore. E ho ottenuto il seguente risultato:

1 thread : Intel : Calculations test : 43ms
100 threads : Intel : Calculations test : 225ms

1 thread : Intel : Allocations test : 35ms
100 threads : Intel : Allocations test : 1754ms

1 thread : SPARC : Calculations test : 197ms
100 threads : SPARC : Calculations test : 261ms

1 thread : SPARC : Allocations test : 236ms
100 threads : SPARC : Allocations test : 1517ms

SPARC mostra il suo potere qui da superando Intel su 100 thread.

Qui va la prova di calcolo multi-threaded:

import java.util.ArrayList;
import java.util.List;

import net.sourceforge.groboutils.junit.v1.MultiThreadedTestRunner;
import net.sourceforge.groboutils.junit.v1.TestRunnable;
import junit.framework.TestCase;

public class TM1_CalculationSpeedTest extends TestCase {

    public void testCalculation() throws Throwable {

        List threads = new ArrayList();
        for (int i = 0; i < 100; i++) {
            threads.add(new Requester());
        }
        MultiThreadedTestRunner mttr = new MultiThreadedTestRunner((TestRunnable[]) threads.toArray(new TestRunnable[threads.size()]));
        mttr.runTestRunnables(2 * 60 * 1000);

    }

    public class Requester extends TestRunnable {

        public void runTest() throws Exception {
            long startTime = System.currentTimeMillis();
            long a = 0;
            for (int j = 0; j < 10000000; j++) {
                a += j * j;
            }
            long endTime = System.currentTimeMillis();
            System.out.println(this + ": " + (endTime - startTime) + "ms " + a);
        }

    }

}

Qui va test multi-thread assegnazione:

import java.util.ArrayList;
import java.util.List;

import junit.framework.TestCase;
import net.sourceforge.groboutils.junit.v1.MultiThreadedTestRunner;
import net.sourceforge.groboutils.junit.v1.TestRunnable;

public class TM2_AllocationSpeedTest extends TestCase {

    public void testAllocation() throws Throwable {

        List threads = new ArrayList();
        for (int i = 0; i < 100; i++) {
            threads.add(new Requester());   
        }
        MultiThreadedTestRunner mttr = new MultiThreadedTestRunner((TestRunnable[]) threads.toArray(new TestRunnable[threads.size()]));
        mttr.runTestRunnables(2 * 60 * 1000);

    }

    public class Requester extends TestRunnable {

        public void runTest() throws Exception {
            long startTime = System.currentTimeMillis();
            String a = "dummy";
            for (int j = 0; j < 1000; j++) {
                a += "allocation driven";
            }
            long endTime = System.currentTimeMillis();
            System.out.println(this + ": " + (endTime - startTime) + "ms " + a.length());
        }

    }

}

Altri suggerimenti

E 'la mia comprensione che le macchine UltraSPARC T2-based sono finalizzate alla performance-per-watt, piuttosto che le prestazioni crudo. Si potrebbe provare a dividere il tempo di assegnazione da parte del consumo di energia e vedere che tipo di numeri che si ottiene. :)

C'è una ragione si sta eseguendo 1.4.2 invece di 1.6?

L'hardware SunOS è più lento, e la VM può essere un po 'più lento pure.

Non credo che questo sta misurando allocazione della memoria. Per cominciare, c'è un sacco di copie carattere in corso in a += "allocation driven";. Ma ho il sospetto che il vero collo di bottiglia è a ottenere l'output System.out.println(...) attraverso gli strati di rete dal app sul server Sun alla stazione di lavoro a distanza.

Come esperimento, provate moltiplicando il numero di ciclo interno da 10 e 100, e vedere se questo "accelera", il server Sun relativa alla stazione di lavoro.

Un'altra cosa che si potrebbe provare è quello di spostare il ciclo interno in una procedura separata. E 'possibile che dal momento che si sta facendo tutto il lavoro in un'invocazione main, il compilatore JIT non ha la possibilità di compilarlo.

(Artificiale "micro-benchmark" come questo sono sempre suscettibili agli effetti come questi. Io tendo a diffidare di loro.)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top