Javaのメモリ割り当てのパフォーマンス(Windowsの対のSunOS)
-
20-09-2019 - |
質問
私は、文字列の多くを割り当て、非常に単純なユニットテストがあります:
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(インテルCore Duoプロセッサ、2.2GHzの、2GB)で、これは平均的に印刷ます:
...
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-エンタープライズ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
日のスーパーサーバが遅い理由を誰も説明できますか?
( http://www.sun.com/servers/coolthreads/ T5120 / performance.xmlする)
解決
CPUは確かに遅いSPARC(1.2GHzの)上で、SunのエンジニアT2のいずれかによって答えとして、現代のIntelプロセッサよりもシングルスレッドのアプリケーションのためのusualy 3倍遅くなります。しかし、彼はまた、マルチスレッド環境でSPARCがより速くなるべきであると述べています。
Iは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は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());
}
}
}
他のヒント
これは、UltraSPARC T2ベースのマシンは、ワットあたりの性能ではなく生のパフォーマンスよりも狙っているというのが私の理解です。あなたは、消費電力によって割り当て時間を分割してみて、あなたが得る数字の種類を見るかもしれません。 :)
あなたは1.4.2ではなく1.6を実行している理由はありますか?
SunOSのハードウェアが遅くなり、そしてVMも多少遅くなることがあります。
私は、これは、メモリの割り当てを測定しているとは思いません。スタートのために、a += "allocation driven";
で起こった文字のコピーの非常に多くがあります。しかし、私は本当のボトルネックがリモートワークステーションにSunのサーバ上のアプリケーションからネットワーク層を通してSystem.out.println(...)
からの出力を得ることであることを疑うます。
実験として、10および100によって内部ループ回数を乗算してみてください、それはあなたのワークステーションにSunサーバー相対を「スピードアップ」かどうかを確認します。
あなたが試みることができるもう一つは、別の手順に内側のループを移動することです。あなたがmain
の1回の呼び出しですべての作業を行っていることから、JITコンパイラがそれをコンパイルする機会を得ることはありません可能性があります。
(このような人工「マイクロベンチマークは、」常にこのような影響を受けやすい。私は彼らを不信する傾向がある。)