2009-08-28 3 views
0

У меня есть очень простой тест модуля, который просто выделяет много строк:Java производительность распределения памяти (SunOS против Windows)

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

    } 

} 

На моем Windows PC (Intel Core Duo, 2,2 ГГц, 2 Гб) это печатает в среднем:

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

JDK версия 1.4.2_18 на обеих машинах. Параметры JVM те же и являются следующими:

–server –Xmx256m –Xms256m 

Может кто-нибудь объяснить, почему SUN супер сервер медленнее?

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

+0

Что вы хотите объяснить? – Mark

+1

Похоже, что первый компьютер быстрее второго. – MicSim

+0

Предположительно, тот факт, что на машине SunOS тест занимает примерно 5-6 раз больше, чем на Windows. – Avi

ответ

2

Процессор действительно медленнее на SPARC (1.2Ghz), и как ответил один из Инженеры Sun T2 обычно в 3 раза медленнее для однопоточного приложения, чем современные процессоры Intel. Хотя, он также заявил, что в многопоточной среде SPARC должен быть быстрее.

Я провел многопоточный тест с использованием библиотеки GroboUtils и протестировал как распределения (через конкатенации), так и простые вычисления (a + = j * j) для тестирования процессора. И у меня есть следующие результаты:

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 показывает свою мощность здесь, превосходя Intel на 100 потоках.

Здесь идет многопоточный тест расчет:

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

    } 

} 

Здесь проходит тест многопоточного распределения:

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

    } 

} 
+0

Является ли последний выход опечаткой? Должен ли это быть SPARC снова? –

+0

Да, вы правы :). Исправлено. –

0

Аппаратное обеспечение SunOS медленнее, и виртуальная машина может быть несколько медленнее, а.

+0

Есть ли способ сделать это быстрее? –

+0

SUN говорит: «Сервер Sun SPARC Enterprise T5120 с технологией Chip Multithreading (CMT) обеспечивает прорывные уровни производительности с огромной экономией мощности и пространства, о чем свидетельствует ряд результатов тестов в мире.» Это не то, что я действительно верю в то, что маркетинг быка дерьмо, но почему это медленнее? –

+0

@Superfilin: педаль сложнее? :-) –

1

Полагаю, что машины на основе UltraSPARC T2 ориентированы на производительность на ватт, а не на сырую производительность. Вы можете попытаться делить время распределения на потребление энергии и посмотреть, какие номера вы получаете. :)

Есть ли причина, по которой вы используете 1.4.2 вместо 1.6?

+0

Требование клиента :) –

+0

Есть ли у вас какие-либо официальные ссылки, которые могут это доказать;)? –

+1

... направленный на «презентацию доллара на каждую точку». Они потребляют почти столько же энергии, сколько процессоры Intel. Может быть на 10-20 Вт меньше, но недостаточно для компенсации потери производительности. – ima

0

Я не думаю, что это измерение распределения памяти. Для начала в фильтре a += "allocation driven"; происходит очень много копий символов. Но я подозреваю, что реальным узким местом является получение вывода от System.out.println(...) через сетевые уровни из приложения на сервере Sun на удаленную рабочую станцию.

В качестве эксперимента попробуйте умножить количество внутренних циклов на 10 и 100 и посмотреть, ускоряет ли это «сервер Sun» относительно вашей рабочей станции.

Еще одна вещь, которую вы могли бы попробовать - переместить внутренний цикл в отдельную процедуру. Вполне возможно, что, поскольку вы выполняете всю работу за один вызов main, компилятор JIT никогда не получает возможности его скомпилировать.

(искусственные «микро-тесты», как это всегда чувствительны к эффектам, как эти. Я склонен доверять им.)

+0

Выражение, которое печатает время, вычисляется до вызова System.out. Итак, это не бутылочная шее. –

+0

Ummm ... это необязательно. Во всяком случае, попробуйте эксперимент. Если вы правы, умножая количество внутренних циклов на N, умножьте время на N. –

+0

Умножение внутреннего цикла на 10 не увеличивает число на 10, так как количество потерянной памяти становится все больше и больше при каждом contcatenation. Он в основном выделяет новый атрибут char [a.length + ", управляемый« .length], и выдает старый массив. Таким образом, на каждой итерации он будет тратить 17 * i символов. Это суммирует до 17/2 * (n^2 - n) как минимум сумму свободной памяти. Таким образом, увеличение внутреннего цикла (n) в 10 раз увеличит время 100 раз. И верьте мне, что System.out здесь не в игре :). –

Смежные вопросы