현대의 많은 시스템 아키텍쳐는 Non-Uniform Memory Architecure(NUMA) 를 사용하고 있습니다. 몇몇 어플리케이션들은 이러한 아키텍쳐들에서 CPU 가 증가함에 따른 확장성에 어려움을 겪고 있습니다. CPU 코어의 추가가 반드시 어플리케이션의 작업수행 능력을 향상 시키는 것은 아닙니다.
이 글에서 필자는 머신의 "NUMAness." 효과를 제거함으로써 NUMA 머신인 썬 SPARC E6900 에서 어떻게 어플리케이션 퍼포먼스를 높였는지 설명할 것입니다. 또한 AMD 옵테론 X4600 에서 어떻게 다른 어플리케이션을 가지고 유사한 결과를 얻었는지에 대해서도 설명할 것입니다. 퍼포먼스 분석을 위한 과학적인 방법들에서 특히 사용되어져 온 용어들에 대해서도 설명할 것입니다. 비지니스 지표(Business Metric)의 중요성을 강조할 것이고 오픈솔라리스 프로젝트 의 NUMA 인식 가능한 툴들의 소개도 제공할 것입니다.
퍼포먼스 분석을 할때에는 우리가 실제로 주의를 기울이고 있는 퍼포먼스와 관계된 모든 지표들을 서로 연관시키는 것이 유용합니다. 이러한 경우에는 단위 시간 당 호출 횟수, 단위 시간당 트랜젝션, 단위 시간당 레코드 처리 등등을 포함합니다. 필자는 이러한 지표를 비지니스 지표(business metric) 라고 부릅니다.
퍼포먼스 지표는 오직 비지니스 지표에서 어떻게 그들이 서로 연관되는지에 대한 구문 안에서만 흥미롭습니다. 비지니스 지표에 대한 효과를 고려함으로써 우리는 지표를 구분하는데에 관계 없는 지표들을 구분하는 것에서 비지니스 지표와 연관된 지표들을 구분해 내는 것으로 조사의 핵심을 이동 합니다. 예를 들어 비지니스 지표의 성과가 tcp 재전송 비율이 증가함에 따라 고통 받고 있다면 tcp 재전송 비율의 향상은 비지니스 지표의 향상을 유도할 것입니다. 유사하게 느린 디스크 I/O 가 비지니스 지표의 하락과 연관되지 않는다면 디스크 I/O 의 향상은 비지니스 지표를 향상시키지 못할 것입니다.
이 글의 그래프는 비지니스 지표와 특정 퍼포먼스 관련 지표들의 판단 방법을 서로 비교할 것입니다.
퍼포먼스 분석을 계획할때에 있어서 시작 전에 실험 파라미터들을 지정해 놓는 것은 매우 유용합니다. 첫째로 우리들은 어떤 것을 연구하고 이룩할 것인지에 대해 설명한 목표를 설정할 것입니다. 이 목표는 비지니스 지표의 범위 아래에 표현됩니다. 목표는 성공의 척도에 대해서도 기술합니다.
이 후에 실험의 유즈케이스들을 결정 합니다. 실제 프로덕션 어플리케이션의 경우 유즈 케이스 는 시스템의 로드가 증가하고 떨어짐에 따란 워크로드 싸이클에 의해 정의 됩니다. 싸이클 상에서 비지니스 지표의 시간별 계산을 캡춰 하는 것이 매우 중요합니다. 실험에서 우리는 반복되는 로드 단계들을 만들어야 합니다. 예를 들어 시간당 백만, 2백만 그리고 3백만의 busy call 은 가상 전화 스위치의 3가지 로드 단계를 정의 합니다. 분석시에 필자는 퍼포먼스 지표와 비지니스 지표 간의 연관성을 찾아 내기 위해 그래프 혹은 가설을 사용할 것입니다.
Non-Uniform Memory Architectures (NUMAs) 는 현대 시스템에서 일반 적입니다. NUMA 아키텍쳐에서 CPU 는 메모리 전부에 대해 동일한 뷰를 가지고 있지 않습니다. 그림 1을 살펴 보시기 바랍니다.
![]() 그림 1. NUMA 아키텍쳐 |
CPU 1 은 고유의 시스템 보드에 있는 메모리에 접근 하는 속도가 CPU 2 가 있는 시스템 보드에 메모리에 접근 하는 것보다 훨씬 빠릅니다.
어플리케이션 쓰레드가 NUMA 아키텍쳐에서 서로 다른 CPU 상에서 실행 될때 CPU 쓰레드가 실행되는 위치에 따라 load 와 혹은 store 의 비용이 서로 다른 환경에서 실행될 수 있습니다. 단위시간당 어플리케이션이 하는 일의 비지니스 지표는 그러므로 어플리케이션이 실행되는 메모리의 거리에 의존적입니다.
SUN SPARC 머신의 한 클래스는 그림 1과 유사하게 중앙 버스 아키텍쳐에 시스템 보드들이 부착되어 있습니다. 머신은 여러개의 시스템 보드들을 가지고 있을 수 있고 각각은 메모리와 CPU 들을 가지고 있습니다. CPU 는 다른 보드에 무착된 메모리에 접근하는 시간보다 CPU 가 위치한 고유 보드의 메모리에 훨씬 빠르게 접근 할 수 있습니다.
AMD 옵테련 기반 머신에서 각각의 CPU 소켓은 HyperTransport 링크에 의해서 서로 연결 됩니다. 메모리 뱅크 접근의 속도는 HyperTransport 링크가 어떻게 순환되야하는지에 따라 다릅니다. 표 1은 몇몇 예제를 나노 초 단위로 제공 합니다.
|
표 1. 메모리 접근 시간의 예 |
|
|
|
썬 파이어 3800-6800 서버 |
썬 파이어 12K/15K 서버 |
|---|---|---|
|
동일한 보드 메모리 접근 |
180-207 |
180-197 |
|
다른 보드의 메모리 접근 |
240 |
333-440 |
썬의 옵테론 기반 플랫폼은 코어에서 로컬 메모리에 접근 하는 시간이 약 80 나노초 정도 걸리고 HyperTransport 링크에 의해 추가적으로 50 나노 초 정도가 더 걸립니다. 듀얼 소켓 플랫폼은 평균적으로 약 105 나노 초 정도의 접근 시간을 보여 줍니다. 쿼드 소켓 시스템의 평균 접근 시간은 124 나노초 입니다. 그리고 8 소켓 시스템에서의 평균 접근 시간은 155 나나초 입니다.
썬 파이어 E6900 서버 는 여섯개의 시스템 보드를 가지고 있습니다. 각각의 시스템 보드는 4개의 소켓을 가지고 있습니다. 우리의 설정에서 각각의 소켓은 64KB L1 캐쉬, 2MB 공유 L2 캐시 그리고 32MB 공유 L3 캐시를 가진 듀얼 코어 울트라SPARC IV+ CPU 을 가지고 있습니다.
어플리케이션은 가상 전화 스위치의 컴포넌트 입니다. 비록 비지니스 지표가 초당 전화 처리 건수 혹은 시간당 통화중 건수로 표현 되겠지만 일반적으로 초당 트랜젝션을 그래프 형태로 표현할 것입니다. 어플리케이션은 여러개의 자바 기반 및 C++ 기반 프로세스들로 이루어 져 있습니다.
문제: 로드가 증가함에 따라 CPU 사용율이 선형으로 증가하지 않습니다. 특히 고객이 하나싀 시스템 보드 설정과 6개의 시스템 보드 설정을 비교했을 때 어플리케이션은 6개 시스템 보드 솔루션에서 오직 3배의 속도 향상을 보여줬는데 이것은 기대되었던 6x 치의 반밖에 안되는 수준 입니다. 다시 말해서 CPU 수가 6배 증가가 6배 만큼의 로드를 처리하지 못했습니다.
목표:
- 당장: 6개 시스템 보드 설정이 감당할 수 있는 로드의 15% 증가
- 6개월 내에: 6개 시스템 보드 설정이 감당할 수 있는 로드의 20% 증가
- 일년 이내에: 6개 시스템 보드 설정이 감당할 수 있는 로드의 50% 증가
계획: 첫째, 4가지의 로드 케이스를 지정합니다: 초당 15,000, 30,000, 45,000, 그리고 60,000 트랜젝션. 다음에 로드 케이스를 순차적으로 실행해서 퍼포먼스 지표들을 수집합니다. 데이타 수집을 위해서 솔라리스 OS 가 제공하는 툴을 사용하는 ksh 쉘 스크립트를 사용해서 퍼포먼스 지표의 타임스탬프를 수집합니다. 그림 2는 CPU 사용율에 따란 비지니스 지표 와 로드의 비교를 나타 냅니다.
![]() 이 곳 을 클릭하면 더 큰 그림을 보실 수 있습니다. |
그림 2에서 100 은 시스템 CPU 용량의 100 퍼센트와 동일 합니다. 비지니스 지표는 초당 트랜젝션으로 나타내어 집니다. 우리가 보고자 하는 것은 로드가 증가함에 따라 CPU 활용율의 증가 입니다. 우리가 보고 있는 것은 CPU 소모량이 3단계에서는 기대 이상으로 4단계에서는 기대했던 것에 2배 이상으로 증가하고 있는 것입니다.
증가하는 사용율의 원인을 찾기 위한 첫번째 단계로는 다른 퍼포먼스 간섭요인들을 찾는 것입니다. 이 것을 위해 mpstat 를 사용할 것이빈다. 이 툴 및 다른 툴에 대한 자세한 정보들은 썬 마이크로시스템즈 문서 사이트 가보시기 바랍니다.
샘플 출력은 다음과 같습니다:
CPU minf mjf xcal intr ithr csw icsw migr smtx srw syscl usr sys wt idl 0 217 0 925 312 206 344 4 133 3024 0 1196 9 3 0 87 1 43 0 1146 36 8 1476 19 492 201 0 1816 10 4 0 86 2 55 0 1108 18 6 1285 5 486 171 0 1665 10 4 0 86 3 45 0 1069 18 7 1238 5 467 169 0 1614 10 4 0 86 4 283 0 1615 18 6 1521 5 517 206 0 2000 11 5 0 84 |
흥미로운 지표들은(꼭 이것들 뿐만은 아니지만) 쓰레드 마이그레이션(thread migrations) (migr), 의도하지 않은 컨텍스트 스위치(involuntary context switches) (icsw), 뮤텍스 락의 스핀(spins on mutex locks) (smtx), 그리고 교차 호출 (xcal) 등 입니다.
쓰레드 마이그레이션(thread migration) 은 쓰레드가 마지막으로 실행된 CPU 와 현재 실행중인 CPU 가 서로 다를 때에 발생합니다. 의도하지 않은 컨텍스트 스위치(nvoluntary context switch) 는 쓰레드가 CPU 코어를 떠남으로써 상위 우선순위의 쓰레드가 실행되거나 쓰레드가 타임 슬라이스를 모두 소모 함으로써 발생 됩니다. 뮤텍스 락의 스핀(Spins on mutex locks) 은 커널에서 뮤텍스 락을 얻기 위해 얼마나 많은 시도들이 실패하였는지를 카운트 합니다. 교차호출(Cross calls) 은 소프트웨어 인터럽트로써 하나의 CPU 코어가 요청을 만족시키기 위해 다른 CPU 에 인터럽트를 걸었을때 방생 합니다. 교차 호출의 많은 원인에는 시그널들과 페이지 매핑 등이 있습니다.
의도하지 않은 컨텍스트 스위치는 쓰레드 마이그레이션을 하므로 인해서 높은 로드 단계들에서의 CPU 사용율 증가와 연관이 있습니다. 그러나 더 흥미로운 증거는 초당 시스템 콜에서 나옵니다. 그림 3을 보시기 바랍니다.
|
|
일반적으로 우리는 단위시간당 어느정도 수준의 시스템 콜을 기대 합니다. 그림 3 의 그래프는 단위 시간당 더 적은 수의 시스템 콜을 하고 있습니다. 이것은 보기 드믄 일입니다. 그러나 시스템이 조건 변수에 poll 이나 timed wait 같은 시간 이벤트 를 사용 하므로써 로드가 증가함에도 시스템 콜을 적게 사용할 수도 있습니다.
필자는 DTrace 를 사용하여 어떠한 시스템 콜이 사용되었는지 추적해 보았고 타임 이벤트가 처리속도 지연의 원인이 아님을 알아냈습니다. 또한 뮤텍스 락의 스핀 또한 느린 시스템 콜의 원인이 아님을 알아냈습니다. 최종적으로 사용자 명령어중 특정 부분이 시간이 오래 걸려서 우리가 기대 했던 것 보다 시스템 콜이 적도록 만들어 졌을 것이라고 가정하였습니다.
load 와 store 가 다른 보드로의 CPU 마이그레이션 과 L3 캐시 미스에 의해 기인하는지(결과적으로 명령당 더 많은 사이클을 사용함) 알아보는 데에 촛점을 맞추기로 하였습니다.
운좋게도 솔라리스는 하드웨어 퍼포먼스 카운터를 접근 할 수 있는 툴인 cpustat 을 제공합니다. E6900 에서 다음의 커맨드를 이용해서 미스 비용을 측정할 수 있습니다:
cpustat -c pic0=Cycle_cnt,pic1=Re_L3_miss 10 100 (샘플당 10초, 100개의 샘플) |
예제의 결과는 다음과 같고 여기서 pic0 은 사이클 카운트 이고 pic1 은 사이클 상에서 L3 미스 비용 입니다 (Re_L3_miss):
time cpu event pic0 pic1 10.008 8 tick 264339684 64702523 10.008 16 tick 379033424 82264350 10.009 17 tick 139120474 43937429 10.009 2 tick 188557829 40718416 10.008 1 tick 196036061 51324303 10.009 9 tick 147137952 31141793 10.008 512 tick 179496352 47598315 10.009 514 tick 213559632 51053565 10.009 10 tick 146540546 29848051 10.009 18 tick 197444045 54358956 10.009 3 tick 241315996 59839941 10.009 515 tick 169493146 37817954 10.009 11 tick 206307589 48544746 10.009 19 tick 139896698 38977705 |
Cycle_cnt 에 대한 L3 미스 비용(Re_L3_miss)의 비율을 계산해 보면 L3 캐시 미스를 위해 몇 퍼센트의 CPU 가 사용되었는지를 볼 수 있습니다. 그림 4의 그래프를 보시기 바랍니다.
|
|
결과는 41 퍼센트의 시스템이 L3 미스에 사용되었습니다.
우리는 다음과 같은 해결방법을 생각해 보았습니다: 프로세서 친밀성(processor affinity) 및 Igroups.
솔라리스는 프로세스 친밀성(processor affinity) 을 내장하고 있고 이것은 쓰레드가 이전에 실행되었던 곳에서 다시 실행되도록 하는 경향을 줄 수 있습니다. 스케줄러는 쓰레드가 얼마만에 실행되었는지와 쓰레드가 이전에 실행 되었을때의 런 큐의 사이즈를 고려 합니다. 간단히 설명하자면 만약 실행 된지 오래 되었거나 원하는 CPU 코어의 런 큐가 너무 많이 쌓였다면 쓰레드는 마이그레이션 됩니다. 당연히 프로세스 친밀도가 쓰레드가 같은 CPU 코어에서 계속적으로 실행 되는 것을 완벽히 보장해 주지는 않습니다..
솔라리스는 Igroups 이라고 하는 컨셉을 가지고 있습니다. lgroup 은 CPU 들의 셋으로 메모리에 대한 동일한 뷰를 가지고 있습니다. 여러분은 NUMA 아키텍쳐를 인식 가능한 툴들을 찾으실 수 있습니다. 이러한 툴들은 다음과 같습니다:
lgrpinfo(1): Igroup 계층, 내용 및 특성들을 출력하는 Perl 스크립트plgrp(1): 홈 Igroup 과 Igroup 친밀성을 관찰하고 영향을 줄 수 있는 proc 툴pmadvise(1):madvise(3C)의 조언을 적용할 수 있는 proc 툴pmap(1)특정 프로세스의 주어진 가상 주소를 백업하고 있는 물리적인 메모리를 가지고 있는 Igroup 을 출력해 주는 확장ps(1)Igroups 확장prstat(1)Igroups 확장
NUMA 아키텍쳐 인식 가능한 툴들의 출력 샘플이 아래와 같습니다.
plgrp -l 12502 의 샘플 출력 예 입니다:
PID/LWPID HOME 12502/1 1 12502/2 3 12502/3 4 12502/4 5 12502/5 2 12502/6 6 12502/7 1 12502/8 4 12502/9 5 |
HOME 컬럼의 숫자들은 각각의 경량 프로세스(lwp) 에 대한 홈 Igroup 을 나타 냅니다.
pmap -x -L 5962 의 출력 결과 입니다:
5962: xxxx 00010000 8K r-x-- 6 xxxx 00020000 8K rwx-- 6 xxxx 00022000 800K rwx-- 6 [ heap ] 000EA000 8K rwx-- - [ heap ] 000EC000 40K rwx-- 6 [ heap ] 000F6000 8K rwx-- - [ heap ] 000F8000 32K rwx-- 6 [ heap ] 00100000 32K rwx-- - [ heap ] 00108000 8K rwx-- 6 [ heap ] 0010A000 32K rwx-- - [ heap ] 00112000 8K rwx-- 6 [ heap ] 00114000 32K rwx-- - [ heap ] 0011C000 216K rwx-- 6 [ heap ] 00152000 32K rwx-- - [ heap ] 0015A000 1416K rwx-- 6 [ heap ] 002BC000 1008K rwx-- 3 [ heap ] 003B8000 32K rwx-- - [ heap ] 003C0000 8K rwx-- 3 [ heap ] ... FF3B0000 184K r-x-- 6 /lib/ld.so.1 FF3E6000 8K r-x-- 4 /lib/libthread.so.1 FF3E8000 8K r-x-- - /lib/libthread.so.1 FF3EE000 8K rwx-- 6 /lib/ld.so.1 FF3F0000 8K rwx-- 6 /lib/ld.so.1 FF3F8000 16K r-x-- 6 /lib/libpthread.so.1 FF400000 24K ----- - [ anon ] FFB2C000 848K rwx-- 6 [ stack ] total 3320488K |
6, 3,그리고 4 는 Igroup 이 어떠한 메모리에서 할당되었는지를 나타 냅니다.
pmap -xL 을 사용해서 우리는 관찰중인 프로세스의 메모리 상에서의 메모리 할당 분산도를 확인할 수 있습니다. 또한 plgrp 를 이용해서 관찰중인 쓰레드가 각각의 다른 시스템 상에서 홈 Igroup 들을 가지고 있음응 확인 할 수 있습니다.
필자가 생각해 낸 첫번째 해결책은 프로세스의 모든 쓰레드들을 동일한 Igroup 에 지정하는 것입니다. 필자는 프로세스 배정을 모든 시스템 보드 상으로 분배 하였습니다. Igroup 친밀도가 보드 간의 마이그레이션 및 L3 미스 비용을 줄여 줄 것으로 기대 했습니다. 그러나 퍼포먼스 향상은 10 ~ 15 퍼센트로 아주 약간 증가 했습니다. 좀 더 과감한 행동이 필요했습니다.
이제 프로세서 셋을 고려하기 시작했습니다. 프로세서 셋은 배타적으로써 필자는 로드의 언밸런스한 분배에 대한 위험 없이 모든 프로세서들을 프로세서 셋들에 지정하는 방법을 알지 못합니다.
마지막으로 프로세서 바인딩에 대해 고려했습니다. latency 에 민감한 쓰레드들을 고유의 CPU 에 바인드 하는 것입니다. 프로세서 바인딩의 위험성은 하나의 쓰레드가 PCU 에 바인딩 되고 나면 그것은 오직 그 CPU 에서만 실행 될 수 있습니다. 이것은 매우 위험한데 왜냐하면 바로바로 실행이 안될수 도 있고 CPU 싸이클이 부족함에 영향을 받을 수도 있기 때문입니다. 이러한 위험을 고정 우선순위 (Fixed Priority, FX) 스케줄링 클래스를 매우 큰 타임 슬라이스에서 높은 우선순위로 실행되도록 쓰레드를 바운딩 함으로써 줄여줄 수 있습니다. 이 해결방법은 마지막 해결책으로 제공되었습니다.
아래의 커맨드를 이용했습니다:
- 쓰레드 혹은
lwp를 바인드 하기 위해(솔라리스 9 과 10에서 쓰레드와lwp사이는 1:1 연관관계가 있음):
pbind -b processor_id pid/lwpid
- FX 스케줄링 클래스에 PID 를 지정하기 위해:
priocntl -s -c FX -m 59 -p 59 -t 300 -i pid "PID"
즉 우선순위 59, 300 밀리 초 타임 슬라이스.
그림 5의 그래프는 필자의 노력 이후에 향상된 확장성을 보여주고 있습니다.
|
|
초당 99,000 트랜젝션 대 60,000 트렌젝션은 꽤 큰 향상 입니다. 이러한 확장성은 L3 미스 비용의 안정화로 인한 것으로 결론지을 수 있습니다. 비록 의도하지 않은 컨텍스트 스위치와 쓰레드 마이그레이션을 줄였줬지만 퍼포먼스 향상의 가장 큰 원인은 그림 6에서 보듯이 L3 미스 비용의 절감 입니다.
|
|
썬 파이어 X4200 은 두개의 소켓을 가지고 있고 각 소켓은 두개의 코어를 가지고 있습니다. HyperTransport 의 메모리에 대한 최대 hop 숫자는 1 입니다. V40z 는 4개의 소켓을 가지고 있고 각각 두개의 코어를 가지고 있습니다. 메모리에 대한 최대 hop 은 2 입니다. 그러나 썬 파이어 X4600 서버 는 8개의 소켓을 가지고 있고 각각 2개의 코어를 가지고 있습니다. 이제 메모리에 대한 hop 의 최대는 3이 됩니다. X4600 의 평균 메모리 접근 시간은 155 나노 초 이고 두개의 소켓을 가진 시스템에서의 105 나노 초와 비교 됩니다.
분석된 어플리케이션은 자바 기반 입니다. 문제는 다음과 같습니다. X4200 서버는 214 분 동안 특정한 양을 처리할 수 있습니다. 이것은 하나의 자바 가상 머신(JVM)* 과 4개의 워커 쓰레드로 수행된 결과 입니다. 어플리케이션이 X4600 서버에 하나의 JVM과 16개의 워커 쓰레드로 배치 되면 실행 시간은 195분입니다. 목표는 X4600 에서 어플리케이션의 실행 속도가 X4200 에 비해 1/4로 줄어 드는 것입니다.
그림 7은 X4600의 소켓 레이아웃을 보여주고 있습니다.
|
|
거의 실시간의 CPU 활용율을 출력하는 perfbar 라고 하는 썬의 내부 툴을 이용하여 우리는 자바 프로세스가 싱글 쓰레드가 되는 시기가 있음을 파악 하였습니다. 가비지 콜렉션의 출력을 시작 시켜봄으로써 싱글 쓰레드가 되는 구간이 가비지 컬렉션이 발생하는 시기 임을 확인 하였습니다. 어플리케이션을 여러개의 자바 프로세스로 분리하도록 결정 하였습니다. 왜냐하면 워크로드는 기본적으로 배치성이었고 복수개의 프로세스간에 작업을 밸런싱 하는 것은 매우 수월하기 때문입니다. X4600 서버가 X4200 에 비해 4배나 코어를 많이 가지고 있으므로 우리는 자바 프로세스를 4개로 나누기로 결정하였습니다.
각 소켓은 듀얼 코어 CPU 를 포함하고 있음을 다시 기억해 봅시다. 하나의 X4600 서버(16 코어) 를 4 개의 X4200 서버( 4 코어) 와 동일한 방식으로 작동하게 하기 위해서는 X4600 을 프로세서 셋으로 나눔으로써 각각의 셋이 X4200 과 닮도록 만드는 것입니다. 그림 7에서 우리는 소켓 0, 1 그리고 2, 4 그리고 3,5 그리고 6, 7을 서로 짝짓기를 원합니다. 다른 조합 또한 가능합니다.
이러한 파티셔닝을 위한 커맨드는 다음과 같습니다:
#delete any existing processor sets psrset -d 1 2 3 #create processor set 1, assign cores 0,1 and 2,3 to processor set 0 (sockets 0 and 1) psrset -c -F 0 1 2 3 #create processor set 2, assign cores 4,5 and 8,9 to processor set 1 (sockets 2 and 4) psrset -c -F 4 5 8 9 #create processor set 3, assign cores 6,7 and 10,11 to processor set 2 (sockets 3 and 5) psrset -c -F 6 7 10 11 # which leaves Cores 12,13 and 14,15 in the default set (sockets 6 and 7) Use FX(Fixed Priority scheduling, $$ = pid of interest) priocntl -s -c FX -m59 -p59 -t300 -i pid $$ in /etc/system, set lgrp_mem_pset_aware=1 set lgrp_mem_default_policy=3 ( LGRP_MEM_POLICY_RANDOM_PSET)
위와 같이 변경함으로써 메모리 할당이 프로세서 셋 내에서 발생하도록 할수 있습니다.
싱글 자바 프로세스를 4개로 나누고 각각을 하나의 프로세서 셋에 배정하고 FX 스케줄링을 사용하고 프로세서-셋과 연관된 메모리 할당을 함으로써 우리는 195 분 걸리던 작업을 80분 아래로 완료할 수 있었습니다. 우리의 목표치에 도달하지는 못했지만 80분은 꽤 큰 성능향상임에는 틀림이 없습니다.
통함 메모리 관리 유닛은 현대 프로세서에 로컬 메모리 접근시에 상당한 퍼포먼스 이득을 가져다 줍니다. 이러한 이득은 메모리 접근이 너무 원격에서 이루어질때에 점점 작아 지게 됩니다.
현대의 시스템은 실행 효율성을 최대화 하기 위해 3가지 방법을 찾고 있습니다: 쓰레드에 그것이 가장 마지각으로 실행되었던 프로세서에 대한 친밀도를 주는 것, 쓰레드가 접근이 필요한 메모리(솔라리스의 Igroup) 와 "가장 가까운" 곳에 있는 프로세서에 대한 친밀도를 주는 것, 그리고 대용량의 L2 L3 캐시를 사용하는 것 등입니다. 종종 이러한 정책들이 실행의 효율성과 확장성을 높이는데에 충분치 않을 수도 있습니다.
지능적인 정책 기반 스케줄링이 도움이 될 수도 있습니다. 그러나 운영체제가 스스로 그런일 을 할 수는 없습니다. 워크로드에 대한 충분한 지식이 있는 경험있는 분석가가 부드럽게 돌아가는 효율 적인 시스템과 확장성이 뛰어나지 못하고 에러가 유발되고 있는 시스템 간의 엄청난 차이를 만들 수 있습니다.
* 여기에서 용어 "자바 가상 머신" 혹은 "JVM" 은 자바 플랫폼의 가상 머신을 의미 합니다.
Solaris Memory Placement Optimization and Sunfire Servers (PDF), 기술 문서, 썬 마이크로시스템즈, 2003년 3월.
Sunfire X4600/X4600M2 Server Architecture (PDF), 기술 문서, 2007년 5월.
Richard McDougall 과 Jim Mauro, Solaris Internals, 2nd edition, 썬 마이크로시스템즈 Press, 2006.
비지니스 지표와 그의 중요성에 대한 개념을 만들어 낸 썬의 Bob Sneed 에게 감사 드리고 이 문서를 리뷰해 준 Jim Fiori 에게도 감사에 인사를 전합니다.
Rickey C. Weisner 는 썬 마이크로시스템즈의 시니어 엔지어입니다. 현재 U.S. 시스템 프랙티스에서 솔라리스의 적용을 위한 일을 하고 있습니다. 주로 퍼포먼스 분석 과 C, C++ 소프트웨어 개발 입니다.
이 글의 영문 원본은
http://developers.sun.com
에서 보실 수 있습니다.










전체

댓글을 달아 주세요
댓글을 쓰시려면 로그인해주세요.