Category Archives: SoC & IP design

듀얼코어? 쿼드코어?

요즘 들어 듀얼 코어가 일반화되었습니다.
AMD의 X2시리즈를 필두로 데스크탑 시장을 열기 시작하더니, 인텔의 코어듀오시리즈가 이제 본격적으로 어필하고 있는 상황입니다.
AMD는 예전부터 2007년 2분기에 Quad Core를 예정하고 있었고, 얼마전에 인텔 개발자 포럼(IDF)에서 인텔 콘로 쿼드 코어가 2007년 1분기에 출시된다고 선언한적이 있습니다. 그 발언과 더불어 쿼드코어가 네티즌들에게 많이 이야기가 되고 있구요..
”]
쿼드 코어가 기술적인 혁신인가?
간혹 이야기를 보다보면, 쿼드 코어가 대단한 기술적 혁신으로 받아들이는 경우가 있는데.. 사실은 아닙니다. 단지 마케팅적인 요소이지요. 사실 온칩 멀티프로세서(CMP)라 불리는 기술은 최소한 10년이상된 기술입니다. 제가 석사과정에서 했던 일도 네개의 정수코어와 한개의 그래픽 코프로세서를 통합하는 프로젝트였으니까요.. (벌써 8년전일이니.. 오래된 일이죠? 외국에서는 훨씬 오래전부터 시작되었습니다.)
사실 더 깊고 넓은 파이프 라인을 만드는 것 보다, 여러개의 코어를 하나의 칩에 통합하는 칩 멀티프로세서 기법이 기술적으로는 좀더 편한 방법입니다.

왜 지금까지 널리 사용되지 않았을까요?
바로, 데스크탑 시장에서는 멀티 프로세서를 사용할 수 있는 소프트웨어가 거의 없었기 때문입니다.
멀티 프로세서를 지원하는 윈도우 데스크탑 OS는 아마도 XP가 최초인 것으로 기억합니다. (NT/2000은 서버/웍스테이션 급이죠?)
멀티 프로세서 OS라고 해도, 프로세스 수준의 멀티 프로세싱을 지원하겠지만.. 데스크탑에서 사용할 수 있는 병렬성은 빤한 수준입니다. 한마디로 그다지 이득이 없다는 겁니다.

차라리, 클럭 주파수를 올리는 것이 수많은 어플리케이션(소위 벤치마크라 이야기되는 부분)에서 사용자에게 어필할 수 있었습니다.

이제는 왜 칩 멀티프로세서가 각광 받을까요?
바로, 주파수 올리기가 어느정도 한계에 도달했기 때문입니다. 주파수 올리기는 필수적으로 전력소모의 증가를 부릅니다. 깊은 파이프라인은 파이프의 효율성을 떨어트리구요..그래서, 대안으로 칩 멀티프로세서가 유용한 “마케팅” 용어로 사용되는 것 같습니다.
또 한가지 중요한 요인은 멀티프로세서를 사용할 여지가 많은 어플리케이션 “멀티미디어”, “게임”이 점점 더 일반화 되고 있다는 점입니다. (물론, 이 분야의 모든 어플리케이션이 멀티 프로세서에서 위력을 발휘하는 것이 아닙니다.멀티프로세서를 위해서 프로그래밍 된 넘들만 힘을 활용할 수 있습니다.)
즉, 사용자들이 알만한 어플리케이션에서 더 좋은 벤치마크 성능을 보여줄 수 있는 시기가 왔다는 점이겠죠.

소프트웨어가 멀티 프로세서 환경을 결정할 것이다.
궁극적으로는 멀티 프로세서 환경의 구축은 피할 수 없는 조류가 되었습니다. 이 이야기는 사실 70-80년대 부터 나오던 이야기입니다.
하지만, 지금 이 시간까지 멀티프로세서가 힘을 발휘할 수 없었던 가장 큰 이유는 “소프트웨어”의 문제입니다.
프로그래머는 기본적으로 “순차적인”알고리즘에 익숙하고, 순차적인 프로그램을 작성합니다.
예를들어 어떤 연산을 하고, 그 결과를 이용해서 분기하여 계산할 것을 결정하는 등의 알고리즘이죠..
이런 순차적인 알고리즘은 이전의 연산/작업이 뒤의 연산/작업에 상당한 의존성(dependency)를 보여주기 때문에 병렬작업이 거의 불가능합니다. 즉, 멀티 프로세서를 사용하더라도, 절대 이것을 사용할 수 없는 것입니다.

멀티미디어 분야에서는 약간 이야기가 달라지는데요.. 각 픽셀에 대한 연산을 병렬적으로 수행할 수 있는 요소가 많아집니다. 즉, 일반적인 프로그램보다는 병렬성의 가능성이 더 높다는 것이죠.. (데이터 형태에서..)
물론, 프로그래머가 병렬성을 살리지 못하면 여전히 멀티 프로세서에서 좋은 결과를 기대할 수 없겠지만 말입니다.

멀티프로세서 환경은 데스크탑 환경에서도 피할수 없는 조류로 자리잡았습니다.
이제, 공은 OS/Compiler/프로그래머에게 넘어갔습니다.

신화의 세계에 살것인가?

개인적으로 SoC에서 가장 재미있게 생각하는 부분이 검증/디버깅입니다.

처음부터 버그없는 넘을 만들면 좋겠지만, 그럴수 없다면 효과적인 검증과 디버깅은 “비용을 소모하는 부수적인 일”이 아니라 이미 필수적인 일인 것입니다.

간혹 몇몇 경영자분들께서 “자신이 실수를 하고 자신이 디버깅하는데 시간과 돈을 소모하는 건 전적으로 엔지니어의 부주의다.”라고 말씀하시곤 하는데, 50%는 납득하지만, 50%는 절대 납득할 수 없습니다.

부주의에의 해서 생긴 버그, 스팩 이해에 문제로 인한 버그, 전달 과정에서의 버그, 초기 아키텍쳐에 의한 버그.. 이 모든 것이 발생하지 않게 완벽한 스팩과 작업을 할 수 있는 사람이 있으리라 생각하지 않기 때문입니다.

아.. 오늘의 이야기에 들어가서.. 디버깅하시는 스타일을 보면 참 여러가지 부류가 있습니다.

검증/디버깅의 기본은 “원인의 파악”이겠죠?

그런데, 그 원인 파악이 아주 아주 어려울때가 있습니다. 수많은 로직들에 연관 관계가 있고, 게다가 타이밍에 의한 영향까지 받는경우 말입니다.

간혹 이런 경우에, 좀 찾으시다가.. 재미난 이유를 대시는 분들이 있습니다.

마치 “고양이가 코드를 먹어버리는 바람에 코드가 사라졌어요” [이 문장은 제가 어느 책에서 본 문장입니다.] 라던지 “낮에는 죽는데 밤에는 안죽네요..” 같은 이유 말입니다.

아.. 얼마나 고생했으면 그런 생각이 다 들겠습니까?

하지만, 신화속에 들어가는 순간 버그는 절대 사라지지 않습니다.

적어도 디지털 회로에서 신화속에 사는 버그란 없습니다. (아날로그 회로에는 아날로그 행운의 신이 있다고 믿는 분들이 많으시고.. 저도 일부 믿습니다.. ^^; )

자.. 디버깅/검증에서 또 한가지 주의해야 할 사항이 있습니다.  바로 “이 일은 절대 일어날 수 없어 ” 라는 것입니다. 이런 신념은 눈앞에서 지나가는 벌레를 그냥 못보고 지나치게 할 수 있습니다.

네.. 바로 눈앞에서 일어나고 있는 일을 그냥 모른채 할 뿐인거죠..

여러분은 “절대 일어날 수 없는 일”을 디버깅하는 것이 아니라 “지금 그 일이 일어났으니까..” 디버깅 하는 겁니다.

현실에서 도망가지맙시다.

이제 튼튼한 올가미 몇개를 준비할 차례입니다.

몇몇 책에서는 shot-gun이라 말하기도 하더군요… [verification plan (james저)]

여하튼 의심나는 곳, 절대 일어날 수 없다고 생각하는 곳 모두에 던져 봅시다.

그리고, 선입관을 버리고 찾아나가다 보면 결국 찾을 수 있을 것입니다.

점점 확신을 얻어가게 될때도 항상 “다른 가능성”을 열어두면서, 범위를 좁혀가면 얼마 시간이 지나지 않아서 올가미에 벌레가 딸려 올라오는 걸 보게 될 것입니다.

잡기 어려운 버그일수록 잡았을때 기쁘지 않겠습니까?

버그찾기란 그런것이니까요..

자! 즐깁시다….

p.s. 요즘 버그잡기에 한창입니다. 신화에 빠지지 않으려 써봤습니다.

캐쉬를 신봉하지 말지어다.

가끔.. 정말 가끔.. 캐쉬를 신봉하시는 분들이 계십니다. 언제나 어디서나 누구에게나 캐쉬가 좋다! 라는 분들이지요.

캐쉬 메모리는 기본적으로 지역성의 원리(principle of locality)를 이용하는 메모리입니다.
즉, 이 세상의 대부분에 적용되는 80:20의 원리.. 이것이 캐쉬에서도 적용되어서 “메모리 접근중의 대부분은 특정한 부분에 이루어진다.”라는 특성을 지니게 됩니다.

세상의 일반적인 원리(?)를 이용한 것이니, 대부분의 어플리케이션에서는 캐쉬를 사용함이 타당합니다.
하지만, 항상 그러냐구요?
예외없는 법칙이 없듯이 캐쉬에서도 마찬가지 입니다.
캐쉬가 힘을 제대로 못쓰는 경우는 “지역성이 없는 데이터”입니다. 당연하겠죠? 지역성을 이용하는 메모리인 캐쉬이니, 지역성이 없는 데이터는 쥐약입니다.

그럼, 지역성 없는 데이터는 어떤것이 있을까요? 캐쉬의 1 라인이 4개 워드를 저장하는 구조라고 합시다.
4 x 4 배열 두개를 만들어봅시다. 배열에서 가장 많이 사용하는 연산이 뭐죠? 내적..
접근은  x(0,0) y(0,0) x(0,1) y(1,0) x(0,2) y(2,0) x(0,3) y(3,0) 이런식이죠? x는 비교적 순서대로 접근했으니 캐쉬 hit이 자주 납니다. 근데, y는 어떻죠? 계속 miss가 발생합니다. 공간적 지역성이 캐쉬에서 예측한 지역성의 수준보다 크기때문에, miss가 발생하는 겁니다.

좀더 심각하게 생각해 볼까요? 하나의 배열에서 저런 접근 하나만 하고, 더 이상 사용하지 않고 다른 배열을 씁시다. 이런 경우가 없다고요? 동영상이 연속된 배열의 입력이란건 알고 계시죠? ^^;

네, 멀티미디어 데이터는 많은 경우 시간적 지역성이 부족합니다. 동영상은 공간적 지역성도 부족할때가 많구요.
그래서, 멀티미디어 처리를 목적으로 하는 프로세서들에는 내장  램을 두고 캐쉬는 두지 않는 경우가 빈번합니다. 또한,  배열 데이터는 특정한 패턴이 있으므로 prefetcher라는 유닛을 두고 프로세서가 필요로 하기 전에 데이터를 내부 RAM에 넣어서, 접근을 빠르게 하는 경우가 많습니다.

이런 경우에 캐쉬가 영 잼병이냐구요?
음.. 네.. 솔직히 캐쉬가 멀티미디어 데이터에 있어서만은 잼병이 될때가 많습니다. 프로그래머분들께서 세심하게 다루어주지 않으시면 말입니다. 사실 캐쉬의 동작은 프로그래머가 프로그램을 얼마나 “캐쉬에 효과적으로” 짜 주시느냐에 따라 달라집니다.

캐쉬에 효과적이려면 어떤 것일까요?
당연히 “지역성의 원리”를 따를 수 있도록, 배열을 잘게 짤라서 공간적 지역성을 찾아수록 좋습니다.
또, 하나의 배열에 대해서 어떤 처리를 해야 한다면 최대한 그 배열에 대해서 어떤 동작을 많이 취해주는 것이 좋습니다.
예를 들어, 이미지의 화질을 개선하기 위해서 상호 보간하고, 밝기를 조정하는 동작을 한다면 모든 화면에 대해서 보간하고 난 이후에 밝기를 조절하는 것 보다는, 잘게 짜른 매크로 블럭에 대해서 보간, 밝기 조정을 같이 수행하는 것이 아무래도 캐쉬에게 좋습니다.

요즘처럼 프로세서가 빨리 도는 세상에, 캐쉬 동작까지 고려하시는 분이 어디있겠습니까만.. (엔진을 만든다던지 하시는 분 이외에는 말입니다.), 염두에 두면 아무래도 더 좋겠죠…
물론, 많은 분들께서 캐쉬도 잘 고려해주는 좋은 컴파일러를 찾으시겠지만 말입니다.