문제

많은 문자열을 할당하는 매우 간단한 단위 테스트가 있습니다.

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.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-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 Super Server가 왜 느려지는지 설명 할 수 있습니까?

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

도움이 되었습니까?

해결책

CPU는 실제로 SPARC (1.2GHz)에서 느리게 느리고 Sun의 엔지니어 중 한 명이 대답 한 바와 같이 현대 인텔 프로세서보다 단일 스레드 애플리케이션의 경우 3 배 느립니다. 그러나 그는 또한 멀티 스레드 환경에서 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는 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.6 대신 1.4.2를 실행하는 이유가 있습니까?

Sunos 하드웨어는 느리고 VM도 약간 느릴 수 있습니다.

나는 이것이 메모리 할당을 측정한다고 생각하지 않습니다. 처음에는 끔찍한 캐릭터 복사가 있습니다. a += "allocation driven";. 그러나 나는 실제 병목 현상이 출력을 얻는 것으로 의심됩니다. System.out.println(...) SUN 서버의 앱에서 원격 워크 스테이션으로 네트워크 계층을 통해.

실험으로 내부 루프 수에 10과 100을 곱한 다음 워크 스테이션에 비해 SUN 서버의 "속도를 높이"하는지 확인하십시오.

당신이 시도 할 수있는 또 다른 것은 내부 루프를 별도의 절차로 옮기는 것입니다. 한 번의 호출로 모든 작업을 수행하고 있기 때문에 main, JIT 컴파일러는 결코 컴파일 할 기회를 얻지 못합니다.

(인공적인 "마이크로 벤치 마크"는 항상 이와 같은 효과에 취약합니다. 나는 그것들을 불신하는 경향이 있습니다.)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top