클럭, 멀티코어, 멀티스레드가 무엇인지 알아보고 이것이 CPU 속도와 어떤 관계가 있는지 학습해보자.
컴퓨터 부품들은 '클럭 신호'에 맞춰 일사분란하게 움직인다. 그 말은 즉 클럭 속도가 높아지면 CPU는 명령어 사이클을 더 빠르게 반복할것이고, 다른 부품들도 그에 맞게 빠르게 동작할 것이다.
그렇다고 발열 때문에 무작정 클럭 속도를 높힐 수 없기 때문에 클럭 속도만으로 CPU의 성능을 올리는것은 한계가 있다.
앞서 CPU를 '명령어를 실행하는 부품' 이라 설명했었다. 하지만 기술의 발전으로'명령어를 실행하는 부품의 여러 개를 포함하는 부품' 으로 확장되었다. 코어 하나가 '명령어를 실행하는 부품' 인 셈이다.
코어를 여러개 포험하고 있는 CPU를 '멀티코어 CPU' 또는 멀티코어 프로세서 라고 부른다.
근데 코어가 많다고 CPU의 속도가 코어 수 만큼 빠른것은 아니다. 코어마다 처리할 명령어들을 얼마나 적절하게 분배시키냐에 따라서 연산속도는 크게 달라진다.
프로그래밍에서 사용되는 스래드는 CPU에 사용되는 하드웨어적 스레드가 있고 프로그램의 사용되는 소프트웨어적 스레드가 있다.
CPU에서 사용하는 스레드 라는 용어는 보통 하드웨어적 스레드, '하나의 코어가 동시에 처리하는 명령어 단위'를 의미한다.
예를들어 2코어 4스레드 CPU는 "명령어를 실행하는 부품"을 두개 포함하고, 한번에 네 개의 명령어를 처리 할수 있는 CPU 라고 말할 수 있다. 즉 코어 하나당 두개의 명령어를 처리할 수있는 CPU 이므로 멀티스레드 프로세서 또는 멀티스레드 CPU 라고 한다.
멀티 프로세서
명령어를 동시에 처리하도록 만드려면 프로그램 카운터,스택 포인터, 데이터 버퍼레지스터, 데이터 주소 레지스터 등.. 이와 같이 하나의 명령어를 처리하기 위한 레지스터를 여러개가 있는것이다.
편의상 이러한 레지스터 모음을 '레지스터 세트' 라고 표현하겠다.
2코어 4스레드 CPU로 예를 들자면
하나의 코어에 레지스터 세트가 두개 씩 있다고 볼 수 있다.
프로그래밍 언어나 운영체제를 학습할때 접하는 스레드는 라는 용어는 보통 소프프트웨어적 스레드, '하나의 프로그램에서 독립적으로 실행되는 단위' 를 의미한다.
예를들면 NodeJS는 싱글 스레드, Spring은 멀티 스레드이다.
명령어를 동시에 처리하여 CPU를 효율을 최대한 끌어올리는 기법인 명령어 병렬 처리 기법에 대해 알아보자
명령어 처리 과정을 클럭 단위로 나누어 보면 일반적으로 아래와 같이 나눠 볼 수 있다.
1. 명령어 인출
2. 명령어 해석
3. 명령어 실행
4. 결과 저장
여기서 중요한 점은 같은 단계가 겹치지만 않는다면 CPU는 '각 단계를 동시에 실행할 수 있다'는 것이다.
이처럼 생산 라인과 같이 명령어 들을 명령어 파이프라인에 넣고 동시에 처리하는 기법을 명령어 파이프라닝 이라 한다.
파이프라이닝은 높은 성능을 가져오긴 하지면 특정 상황에서 실패하는 경우도 있다.
명령어 1 : R1 <- R2 + R3 // R2 레지스터 값과 R3 레지스터 값을 더한 값을 R1 레지스터에 저장
명령어 2 : R4 <- R1 + R5 // R1 레지스터 값과 R5 레지스터 값을 더한 값을 R4 레지스터에 저장
위의 경우 명령어1 를 수행해야만 명령어2 를 수행할 수 있다. 만약 명령어1 실행이 끝나기 전에 명령어2를 인출하려면 원치 않는 값이 나오게 된다.CPU 내부에 여러 개의 명령어 파이프라인을 포함한 구조를 슈퍼스칼라 라고 한다.
CPU의 언어인 ISA란? , 현대 CPU의 주요 설계 방식인 CISC와 RISC의 정의와 차이점을 알아보자.
CPU가 이해할 수 있는 명령어 모음을 명령어 집합 또는 명령어 집합 구조 (이하 ISA) 라고 한다.
명령어 집합에 '구조'라는 단어가 붙은 이유는 CPU가 어떤 명령어를 이해하는지에 따라 컴퓨터 구조 및 설계 방힉이 달리지기 때문이다.
CPU가 이해하고 실행하는 명령어들은 제조사별로 CPU마다 규격과 기능별로 다르다.
기본적인 구조와 작동원리는 이전에 학습한 내용과 크게 벗어나진 않지만 제어장치가 명령어를 해석하는 방식, 사용되는 레지스터 종류와 개수, 메모리 관리 방법 등.. 많은 것들이 달라진다.
그래서 같은 소스 코드로 만들어진 같은 프로그램이라 할지라도 ISA가 다르면 CPU가 이해할 수 있는 명령어도 어셈블리어도 달라지는 것이다.
예를들면 인텔 CPU 컴퓨터에서 만들 실행 파일을 그대로 아이폰에 옮겨 특별한 설정없이 바로 실행하면 실행이 안된다.
명령어 효율적으로 처리( 파이프라인, 슈퍼스칼라, 비순차적 명렁어 처리 ) 하는 명령어 집합도 있고 그렇지 못한 집합도 있다. 이와 관련해 현대 ISA의 양대 산맥인 CISC와 RISC에 대해 알아보자.
CISC는 Complex Instruction Set Computer ( 복잡한 명령어 집합을 활용하는 컴퓨터 ) 의 약자이다.
CISC기반의 ISA 중 가장 대표적인 종류로는 x86, x86-64 가 있다.
CISC는 다양하고 강력한 기능의 명령어 집합을 활용하기 때문에 명령어 형태와 크기가 다양한 가변 길이 명령어 를 활용한다.
장점
다양하고 강력한 명령어를 활용 한다는 말은 상대적으로 적은 명령어로도 프로그램을 실행할 수 있다는것을 의미한다. 즉 컴파일된 프로그램의 크기가 작다.
단점
활용하는 명령어가 복잡하고 다양한 기능을 제공하는 탓에 명령어의 크기와 실행되기전까지의 시간이 일정하지 않다. 즉, 파이프라인이 효율적으로 명령어를 처리 할 수 없다는것을 의미한다.
CISC의 한계로 두가지 교훈을 얻을 수 있었다.
빠른 처리를 위해 명령어 파이프라인을 십분 활용해야 한다. 원활한 파이프라이닝을 위해 '명령어 길이와 수행시간이 짧고 규격화' 되어 있어야 한다.
어차피 자주 쓰이는 명령어만 줄곧 사용한다. 복잡한 기능을 지원하는 명령어를 추가하기 보다 '자주 쓰이는 기본적인 명령어를 작고 빠르게 만드는 것'이 중요하다.
이런 원칙하에 등장한 것이 RISC ( Reduced Instruction Set Computer ) 이다.
짧고 규격화된 명령어, 되도록 1클럭 내외로 실행되는 명령어를 지향하는것이 특징이다.
RISC는 고정 길이 명령어 를 활용한다.
RISC는 메모리의 접근을 단순화, 최소화하는 대신 레지스터를 적극적으로 활용한다. 그렇기에 CISC보다 레지스터를 이용하는 연산이 많고, 일반적인 경우보다 범용 레지스터 개수도 더 많다. 다만 사용하는 명령어 개수가 CISC보다 적기 때문에 RICS는 CISC보다 많은 명령으로 프로그램을 작동시킨다.