멀티코어 혁명: 멀티코어 구성 방식과 한계

Jin Hur·2021년 8월 23일
0

reference: "프로그래머가 몰랐던 멀티코어 CPU 이야기" / 김민장, "Computer System A Programmers'Perspective" / 랜달 E.브라이언트

멀티코어 구성 방식

일반적으로 많이 쓰는 듀얼코어, 쿼드코어 프로세서는 각 코어가 완전히 같다. 구조도 같을 뿐 아니라 클록 속도와 캐시 크기도 같다. 물론 (물론 최근에는 가변적인 클록이 코어마다 가능하도록 되어 있지만 근본적으로 같은 코어다.) 이러한 멀티코어를 호모지니어스(homogeneous) 멀티코어라 한다. 그러나 최근에는 각 코어가 서로 구조적으로 다르거나, 구조는 비슷하더라도 성능 차이가 있는 코어를 하나의 칩에 만들기도 한다. 이러한 멀티코어 프로세서를 헤테로지니어스(heterogeneous) 멀티코어라고 한다. 한 예로는 CPU와 GPU가 한 칩에 집적되는 것도 헤테로지니어스 멀티코어의 좋은 예이다.

또한 ISA는 같지만, 클록이나 캐시 크기를 다르게 해 성능 차이를 두는 방법도 있다. 특별히 이런 헤테로지니어스 프로세서를 비대칭(asymmetric) 멀티코어라고 부른다. 직렬 코드는 높은 클록이 요구되므로 캐시가 많고 속도가 빠른 코어가 담당하고, 병렬 부분은 일반적으로 클록보다는 프로세서 개수가 더 중요하므로 작지만 수가 많은 멀티코어에 맡기는 방식이다.

예를 들어, 70%가 병렬화 가능한 코드를 두 멀티코어 프로세서에서 돌리는 경우를 생각해보자. 두 멀티코어는 모두 트랜지스터 수나 전력 사용량이 같다 가정한다. 첫 번째는 호모지니어스 멀티코어인데 16개의 같은 코어로 만들었다. 그리고 다른 하나는 헤테로지니어스 멀티코어로, 코어 8개는 호모지니어스 멀티코어와 같고, 나머지 코어 8개를 만들 비용으로 더 많은 캐시와 더 놓은 클록을 가지는 큰 코어로 만들었다. 그리고 이 코어는 다른 코어보다 2배 더 빠르다 가정한다.

(1) 호모지니어스 멀티코어에서 speedup = 1 / (0.3 + 0.7/16) = 2.91
(2) 헤테로지니어스 멀티코어에서 speedup = 1 / (0.3/2 + 0.7/8) = 4.21

위 speedup은 지나치게 단순화했지만 프로그램 성능은 결국 병렬화할 수 없는 부분에 좌우되므로 이 부분을 빠르게 하는 방법은 효과적이다. 앞으로는 단순한 호모지니어스 멀티코어보다는 구조와 성능이 서로 다른 코어가 힘을 합쳐 전체적인 시스템 성능을 향상시키는 헤테로지니어스 혹은 비대칭 구조가 일반적이 될 수도 있다.


멀티코어의 한계: 메모리 장벽과 병렬 프로그래밍

한계1) 메모리 장벽(memory wall)

멀티코어가 만병 통치약일까?

싱글코어에서 성능을 크게 높이지 못해 멀티코어, 더 나아가 매니코어(many-cores)로 발전해나가고 있다. 2006년 대중적인 듀얼코어 프로세서가 등장한 이후 쿼드코어, 헥사코어(6), 옥타코어(8)도 이미 현실화되었다. 마치 프로세서 세대가 진보함에 따라 클록 속도가 뛰었던 것처럼 코어의 갯수가 지금 그러하다. GPU 역시 그안에 있는 수많은 멀티프로세서의 개수가 증가하고 있다. 더 더 더 많은 코어를 칩 하나에 넣는 것은 물리적으로 가능할지 몰라도 현재 기술로는 이렇게 많은 멀티코어가 별 효용이 없다고 믿고 있는데, 바로 메모리 장벽(memory wall) 때문이다.

멀티코어, 매니코어 환경에서는 메모리 대역폭이 아주 중요하다. 예를 들어 한 코어가 사이클마다 1바이트 데이터를 요청하면 2GHz 프로세서에서는 초당 2GB의 데이터가 필요하다. 만일 100코어라면 100GB/s의 대역폭이 필요하다.(100GB/s? 200GB/s?) 1TB 하드디스크를 10초 내에 몽땅 읽어야하는 엄청난 대역폭이다.

듀얼 채널: DRAM 메모리를 컴퓨터 메인보드에 꼽을 때 쌍으로 꼽아야 대역폭이 높게 나온다는 이야기이다. 인텔은 이것을 확장하여 Core i7과 x58칩셋에서는 트리플 채널을 도입했다. 트리플 채널의 대역폭은 최대 32GB/s에 달한다.

32GB/s 대역폭은 GPU에서 턱없이 부족한데, GPU는 비록 간단한 구조지만 훨씬 많은 코어가 있다. 그래서 GPU는 통상 CPU보다 더 높은 메모리 대역폭을 지원해야 한다. nVidia의 GeForceGTX285(2009년 출시) 그래픽 카드는 대역폭이 160GB/s이 될 정도로 엄청나다. 그럼에도 실제 대용량 데이터를 처리하는 GPU 프로그램의 성능은 메모리 대역폭에 좌우될 때가 잦다.

기존 구조에서는 메모리 대역폭 한계가 있기에 많은 프로세서 코어가 있더라도 일을 할 수 없고 오히려 해악만 끼칠 수 있다. 그런데 만약, 새로운 기술이 도입된다면 성능은 하락하지 않고 증가함을 볼 수 있다. 이 새로운 기술은 3D 스태킹(stacking)이라는 기술로 칩을 고층 건물과 같이 3차원으로 쌓아 올리는 것이다. 이상적으로는 멀티코어 아래에 거대한 DRAM을 바로 한 칩에 넣어 높은 대역폭을 꾀한다. (책의 출판시기 2011년 12월까지는 연구 단계)

그러나 또 하나 근본적인 문제는 바로 암달의 법칙이다. 프로세서 개수가 32개에서 64개가 되어도 성능이 거의 오르지 않을 수 있다. 암달의 법칙에서 보았듯 병렬 가능한 부분이 80%이고, 아무리 많은 프로세서가 있어도 다섯 배밖에 빨라지지 않는다. 만약 프로그램 자체가 직렬로 처리되어야 하는 부분이 많다면 멀티코어가 아무리 많아도 무용지물이 된다.

한계2) 병렬 프로그래밍

source: https://12bme.tistory.com/65

메모리 장벽 문제는 전혀 새로운 것이 아닌게 싱글코어에서도 메모리와 CPU의 속도 차이가 시스템의 병목 지점이었다. 멀티코어는 이 문제를 더 가중시키는 것이다. 그런데 메모리 장벽보다 더 큰 문제가 있는데, 바로 병렬 프로그래밍이다. 만약 프로그래머가 쉽고 효율적인 병렬 프로그래밍을 할 수 없다면 멀티코어는 빛을 발할 수 없다. 멀티코어의 미래는 소프트웨어 개발자들의 손에 달렸다고 해도 과언이 아니다.
병렬 프로그래밍은 인간의 인지를 보통 뛰어넘는다는 원초적인 어려움이 있다. 일반 프로그래밍에는 객체지향 설계와 같은 아주 성공적인 프로그래밍 방법론이 있지만 병렬 프로그래밍에서는 이런 방법론이 아직까지 없다. 프로그램의 병목 지점을 알려주는 프로파일러(profiler)나 디버거(debugger) 역시 병렬 프로그래밍에 최적화되지 않았다.


여전히 중요한 싱글코어 성능

아무리 병렬화해도 거기에는 직렬로 실행되어야 하는 부분이 있다. 이 부분을 빠르게 할 방법은 전통적인 싱글코어 성능 향상 말고는 없다. 아직까지(2011년) 싱글코어의 성능 향상에 있어서 실현가능하다면 엄청난 ILP 값 상승으로 이어질 수 있다는 예측이 있지만, 현실적으로는 비관적인 부분이 많다. 그러나 긍적적으로 바라보면 싱글쓰레드의 잠재력은 충분하다는 것이다. ILP가 죽었기 때문에 멀티코어로 가야한다는 논리가 항상 옳은 것은 아니다.


결론

싱글코어가 성능 향상에 발목이 잡힌 이유는 ILP의 한계, 비순차 프로세서의 한계, 클록 속도의 한계, 에너지 장벽 등에 있다. 그리고 그 대안으로 나온 멀티코어, 병렬 구조가 나왔다.
멀티코어가 앞으로 성공하려면 기술적으로는 메모리 장벽을 해결해야하고, 프로그래머들이 더 쉽게 병렬 프로그래밍을 할수 있어야 한다.

0개의 댓글