Question

J'ai un test unitaire très simple qui alloue seulement beaucoup de cordes:

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());
        }

    }

}

Sur mon PC Windows (Intel Core Duo, 2,2 GHz, 2 Go) cette affiche en moyenne:

...
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
...

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
...

version 1.4.2_18 est JDK sur les deux machines. paramètres JVM sont les mêmes et sont les suivants:

–server –Xmx256m –Xms256m

Quelqu'un peut-il expliquer pourquoi le serveur super SUN est plus lent?

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

Était-ce utile?

La solution

La CPU est en effet plus lent sur SPARC (1.2Ghz) et comme une réponse par l'un des T2 ingénieurs du Soleil est usualy 3 fois plus lent pour une application mono-thread que les processeurs Intel modernes. Cependant, il a également déclaré que dans un environnement multi-thread SPARC devrait être plus rapide.

J'ai fait un test multi-thread utilisant la librairie GroboUtils et testé les deux allocations (par) et concaténations calculs simples (a + = j * j) pour tester le processeur. Et j'ai les résultats suivants:

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 montre sa puissance ici en surpassant Intel sur 100 threads.

va ici le test de calcul multi-thread:

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);
        }

    }

}

va ici le test d'allocation multi-thread:

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());
        }

    }

}

Autres conseils

Je crois comprendre que les machines basées sur UltraSPARC T2 sont destinés à la performance par watt plutôt que les performances brutes. Vous pouvez essayer de diviser le temps d'allocation par la consommation d'énergie et voir quel genre de chiffres que vous obtenez. :)

Y at-il une raison que vous êtes en cours d'exécution au lieu de 1,6 1.4.2?

Le matériel SunOS est plus lent, et la machine virtuelle peut être un peu plus lent aussi.

Je ne pense pas que c'est la mesure de l'allocation de mémoire. Pour commencer, il y a énormément de copie de caractère en cours dans a += "allocation driven";. Mais je soupçonne que le véritable goulot d'étranglement est à obtenir la sortie de System.out.println(...) à travers les couches de réseau à partir de l'application sur le serveur Sun à votre poste de travail distant.

A titre d'expérience, essayez multiplier le nombre de boucle interne de 10 et 100, et voir si cela « accélère » le serveur Sun par rapport à votre poste de travail.

Une autre chose que vous pouvez essayer est de déplacer la boucle interne dans une procédure distincte. Il est possible que, puisque vous faites tout le travail en une seule invocation de main, le compilateur JIT obtient jamais une chance de le compiler.

(artificiels « micro-repères » comme celui-ci sont toujours sensibles aux effets comme ceux-ci. Je tends les méfiance.)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top