The truth will set you free

sunyzero.egloos.com

포토로그 마이가든



멀티코어 시대를 맞이하여 최적화 이슈 1 View point

최근에는 최적화(optimization)가 이슈화 되고 있다. 그 이유는 컴퓨팅 파워에서 하드웨어 부분의 발전이 둔화되었기 때문이다. 사실상 둔화된 것은 아니지만 High clock의 시대가 지나가는 것은 사실이다.

과거에 100Mhz짜리 CPU에서부터 겨우 10여년이 지났을때 2~3Ghz의 클럭을 성공시켰던 것에 비해 최근은 답보상태다. 그리하여 현재는 멀티코어(multi core on die)기술로 방향선회를 한 지 오래다. 그렇다면 왜 멀티코어로 방향을 선회했는가? 그것은 2가지 이유 때문이다.(멀티코어 외에도 다양한 예측 기술과 bandwidth를 효율적으로 사용하는 기술이 활발하게 개발되고 있다)

  1. 첫번째로 고클럭 기술은 거의 한계에 다다르고 있다. 2006년 인텔에 따르면 5GHz가 현재 실리콘 소자로는 한계점에 가깝다고 한다.

  2. 두번째로 고클럭은 전력소모가 너무 심하다. 실제로 4~5GHz로 올리게 되면, 소비전력의 절반정도가 leakage power로 소모되어버린다.
전력소모가 무슨 문제냐 싶은 사람도 있겠지만, 열역학1법칙을 적용하면 소모된 전력은 어떤 형태로든 변하기 마련이다. CPU 같은 반도체 칩에서는 당연히 그 일부가 열 에너지로 발산된다. 그러면 그 발산된 에너지를 냉각하기 위해 또 전력이 소모된다. 실제로 이렇게 소모되는 전력이 CPU 수천장이 소비되는 IDC센터에서는 생각하기도 싫을 정도로 깨지게 된다.

따라서 CPU 벤더들은 고클럭보다는 멀티코어를 사용하게 되었고 이외에도 효율적인 연산을 위해서 효율적인 Cache 관리나 Pipeline의 증설/효율화를 신경쓰게 되었다.

따라서 멀티코어를 효율적으로 사용하기 위해서는 하드웨어에 대한 이해와 작업을 나누는 프로그래밍 기법이 필요하다.


1. CPU 클럭과 파이프라인
일단 CPU는 고클럭이 좋기는 하지만, 절대적인 것은 아니다.

같은 클럭이라고 하더라도 파이프라인이 몇개인지가 중요하다.
만일 파이프라인이 3개라면 최대 동시 처리 가능한 명령어 인스트럭션은 3개가 된다.

현재 대다수의 CPU들은 파이프라인이 4개다. 서로 다른 4개의 명령어가 동시 입력된다면 동시 4개의 명령을 처리할 수 있다는
의미이다. 하지만 현실은 파이프라인의 50%만 활용해도 많이 활용하는 것이다.(그래도 일단은 파이프라인이 많을수록 효율은 높아진다)

2. 멀티코어와 캐시관계
멀티코어가 되면 항상 문제가 되는 것이 캐시이다. 캐시를 공유할 것인지 아니면 따로 가질 것인지가 문제인 것이다.
2차이상의 캐시가 공유되지 않는 경우엔 false sharing 문제에서 비용이 커지기 때문에 쓰레드를 사용할 때 조심해야 한다.
(false sharing에 대한 문제는 나중에 예제를 통해서 살펴보도록 하겠다.)

3. 아키텍쳐구조/OS의 지원
아무리 멀티코어를 사용한다고 하더라도 아키텍쳐나 OS가 멀티코어를 제대로 지원하지 못하면 아무 소용이 없다.

현재 x86계열의 경우는 아키텍처 레벨의 문제로 인해서 16개 이상의 CPU는 효율적인 지원을 할 수 없다.
따라서 quad core를 사용한다면, 4개의 CPU 패키지를 달아주면 거의 Max 효율을 낸다.

또한 OS의 지원도 중요한데, 현재 MS Windows계열의 경우 4개 이상의 CPU는 제대로 활용하지 못한다고
알려져 있다. Windows 2003의 경우는 8개까지도 효율적 분배를 한다고 하지만, 아직 확인해보지는 못했다.

RISC계열의 CPU인 MIPS, PPC, Sparc등은 애초부터 수십개 이상의 CPU 지원을 염두에 두고 만들어져 있다.
따라서 이들 CPU를 사용하는 UNIX들은 Octet 코어 이상의 CPU를 사용하는 경우가 많다.
또한 RISC계열의 CPU는 대부분 저클럭이어도 Memory bandwidth가 높아서 복잡한 연산보다 I/O관련 작업이
많은 작업에서 유리할 수 있다.(몇몇 RISC는 고속연산을 위해서 고클럭을 사용하기도 한다)

예를 들어 웹 서비스는 복잡한 연산보다 데이터 처리를 위한 I/O 작업이 많기 때문에 Memory bandwitdh를
효율적으로 처리하는 아키텍쳐 구조가 좀 더 유리하다.(최근에는 x86계열도 Memory bandwitdh가 높아져서
차이가 많이 줄어들었다. 가격대 효율면에서는 오히려 x86계열이 좋기도 하다)

따라서 저클럭의 웹 전용 서버들은 무거운 WAS보다는 가벼운 apache 같은 서버에 적합한 구조가 된다.
(저클럭의 CPU를 많이 붙인다고, WAS가 빨라지지는 않는다는 뜻이다. 몇몇 블레이드 서버는 저클럭의 I/O를 중시한 모델로 나오므로 잘 봐둬야 한다.)


4. 멀티코어에 대응하는 소프트웨어 기술
멀티코어를 제대로 사용하려면 소프트웨어에 비동기적 기술을 사용하던가 혹은 분기형 프로세스형으로 가야 한다.

UNIX/Linux계열에서는 과거부터 주로 사용한 fork-model을 많이 사용한다. 이는 전형적인 MP(Multi-Process)모델로서
가장 만들기도 쉽고 대다수의 경우 특별한 문제를 일으키지 않는다. 이 기법은 Process pool을 조정하는 기능을 사용한다.
Apache 웹서버 같은 모델이 대표적이다.

그러나 MP모델에는 치명적인 약점이 있다. 그것은 각 프로세스들이 서로 통신을 할 필요가 있으면 IPC(Inter-Process Communication)를 사용해야 한다는 것이다. 따라서 MP모델로 작성할 때는 다음을 신경써야 한다.

  1. 각 프로세스는 독립적으로 작동하여야 한다.
  2. 부득이 하게 각 프로세스가 서로 통신해야 하는 구조라면 적은 양의 데이터 통신을 하여야만 한다.
위의 2가지 문제만 해결된다면 MP프로그램은 작성도 쉽고 안정성도 높기 때문에 강력 추천한다. 하지만 서로 통신하는 데이터양이 많아진다면 MP로는 해결이 안된다. 그 이유는 뭘까?

이는 알다시피 CPU는 점차 빨라졌지만 상대적으로 느리게 발전한 것이 Memory(RAM)와 Disk 전송 기술이기 때문이다. 따라서 IPC를 많이 사용하면 CPU에 비해 상대적으로 느린 IPC I/O 때문에 대용량 시스템으로 갈수록 latency가 엄청나게 상승한다. 결국 동시접속자가 많은 시스템이라면 느린 응답속도를 보여주게 된다. 물론 분산 시스템으로 가는 방법도 있겠지만 상대적으로 유지보수 비용이 많이 든다. (분산 시스템은 필수불가결한 요소로서 중저성능의 시스템을 다수개를 배치하게 되고, 분산처리를 위한 네트워크 장비, 복수 개의 서버 관리 비용으로 전력/공간/부수적 비용이 많이 들어간다)

따라서 I/O비용을 줄이는 기술로서 쓰이는 것이 Thread나 Signal 기법이다.

대부분의 경우 Thread를 쓰면 I/O wait가 줄어들어 응답성이 좋아진다(Library level thread 제외). 이는 Thread가 프로세스 내에서 메모리 공간을 공유하는 특성 때문이다. 데이터 복사가 뒤따르는 외부 IPC를 사용하지 않으니 당연히 응답성이 좋을 수 밖에 없다. 그러나 쓰레드를 사용하면 메모리 공간을 공유하는 특성 때문에 단 1개의 쓰레드가 메모리를 침범하더라도 프로세스 자체를 종료시키면서 모든 쓰레드가 같이 종료된다는 점이다.(이는 신뢰성 있는 서버형 프로세스에 큰 위협이다.)

또한 쓰레드를 사용하면 기존의 작은 모듈형 MP프로그램을 서로 통합해야 하므로 프로그램이 상대적으로 커지는 단점이 있다. 이는 유지보수에 위협이 되며, 버전관리에도 어려움을 겪을 수 있다.(기존에 모듈형인 경우는 모듈은 독립적이라서 버전에 따라 다른 모듈에 문제를 주는 경우가 적지만, 쓰레드 통합형 프로그램은 한 모듈이 다른 모듈에 밀접한 영향을 주는 경우가 많다.)

그러므로 쓰레드를 사용하는 것은 시스템 프로그래밍에 대한 깊은 이해가 선행되며, 그렇지 않은 경우는 오히려 MP모델보다 신뢰성을 떨어뜨릴 수 있다. 그러면 쓰레드를 사용하려면 어떤 주의점을 가져야 하는가?

이에 대해서는 다음에 이야기 하겠다. 오늘은 여기까지~

* History
2009.09.05  일부 문장 및 오타 개정

트랙백

이 글과 관련된 글 쓰기 (트랙백 보내기)
TrackbackURL : http://sunyzero.egloos.com/tb/3959683 [도움말]

덧글

덧글 입력 영역