ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 컴퓨터 구조 (1)
    프로그래밍/CS 2024. 7. 25. 23:52

    컴퓨터는 소스코드 직접 이해하는 게 불가능해서 실행되기 전 명령어(+ 데이터)로 변환되어 실행됨

     

    저급언어 : 컴퓨터가 이해하기 편한 언어 (ex. 명령어, 데이터)

    • 기계어(machine code) : 0과 1로 표현된 컴퓨터가 직접 이해하는 언어
    • 어셈블리어(assembly language) : 조금이라도 읽기 편하게 기계어를 변환한 언어

     

    고급언어 : 사람(개발자)가 이해하기 편한 언어 (ex. 소스코드)

    1. 컴파일 : 소스코드 전체가 컴파일러(gcc, clang, Visual Studio 등)에 의해 검사, 목적 코드로 변환 (ex. C/C++, Rust)
    2. 인터프리트 : 소스코드를 한 줄씩 인터프리터에 의해 검사, 목적 코드로 변환 (ex. Python, JavaScript)

    (( 언어 변환되는 것 확인해 볼 수 있는 사이트 - godbolt.org ))

    컴파일 방식과 인터프리트 방식은 칼로 자르듯이 명확하게 구분되는 개념 X
    컴파일 방식과 인터프리트 방식의 특성을 모두 갖춘 언어도 있음 (ex. Java, Python)

     

    명령어 : 컴퓨터를 동작시키는 실질적인 정보

    데이터 : 명령어의 대상(재료)

     

    연산코드(op-code) : 수행할 동작

    오퍼랜드(operand) : 명령어를 수행할 대상 = 대상(데이터)이 직접 명시되기도 하고, "대상의 위치(레지스터 이름, 메모리 주소)"가 명시되기도 함, 아예 없을 수도 있고 여러개 있을 수도 있음

     

    명령어 = [오퍼랜드]로 [연산코드]를 수행하라

     

    명령어의 길이는 한정적이어서 데이터를 직접 넣지 않고 데이터가 저장된 위치 명시

     

    유효 주소 : 연산 코드에 사용할 데이터가 저장된 위치

     

    주소 지정 : 유효 주소를 찾는 방법, CPU마다 다름

    1. 즉시 주소 지정 : 연산에 사용할 데이터 직접 명시하는 방법 - 가장 빠른 주소 지정 방법으로 데이터 크기는 제한적임
    2. 직접 주소 지정 : 오퍼랜드 필드에 유효 주소 명시하는 방법 - 표현 가능한 메모리 주소 크기 제한적임
    3. 간접 주소 지정 : 오퍼랜드 필드에 유효 주소의 주소 명시하는 방법 - 유효 주소 크기에 제한 없음, 속도는 비교적 느림
    4. 레지스터 주소 지정 : 사용할 데이터 저장한 레지스터 직접 명시하는 방법 - 메모리 접근보다 속도 빠름
    5. 레지스터 간접 주소 지정 : 데이터는 메모리에 저장하고 유효 주소 저장한 레지스터 명시하는 방법

     

    이진수 : 0과 1만으로 표현된 수

    이진법 : 이진수로 모든 수를 표기하는 방법 [ 숫자가 너무 길어진다는 단점 있음 ]

     

    16진수 : 0~9와 A~F(10~15)로 표현된 수

    16진법 : 16진수로 모든 수를 표기하는 방법 [ 이진수와 상호 변환이 편해서 16진수를 사용하는 경우 많음 ]

     

    2의 보수법 : 0과 1만으로 음수를 표현하는 방법 중 하나 = 이진수로 표현된 수의 모든 0과 1을 뒤바꾼 뒤 1을 더한 값

    컴퓨터에선 CPU 내부의 flag 사용함 (ex. 음수 플래그 세팅되어 있으면 음수, 세팅되어 있지 않으면 양수)

     

    부동 소수점(floating point) : 컴퓨터 내부의 소수 표현 방식

    m X 2^n
    가수 부분(m) : 1.XXX 꼴을 띄고 있음
    지수 부분은 추가로 저장되는 바이어스 값으로 확인 가능
    바이어스 값 : 2^(k - 1) - 1 = k는 지수 비트가 자치하는 비트 수

     

    부동 소수점은 십진수 소수를 이진수로 표현할 때 십진수 소수와 이진수 소수 표현이 딱 맞아떨어지지 않을 수 있음

     

     

    문자 집합(charater set) : 표현 가능한 문자들의 집합

    문자 인코딩 : 문자를 0과 1로 이루어진 문자 코드로 변환

    문자 디코딩 : 0과 1로 이루어진 문자 코드를 문자로 변환

     

    아스키 코드(ASCII)

    아스키 문자 집합 : 초창기 문자 집합으로 알파벳 + 아라비아 숫자 + 일부 특수 문자 + 제어 문자로 이루어져 있음

    = 기본적으로 8비트로 표현(1비트는 오류검출), 확장형 아스키코드에서는 8비트 온전히 사용

    ex. 97을 문자로 출력하도록 하면 a 출력하고, a를 정수로 출력하도록 하면 97 출력

     

    유니코드 - 인코딩 방식 다양함 (home.unicode.org / codepoints.net)

    유니코드 문자 집합 : 대부분의 언어 + 특수문자 + 이모티콘 + 화살표 등으로 이루어져 있음

    유니코드 코드 포인트 : 유니코드 문자에 부여된 고유한 수로 코드 포인트 인코딩 방식에 따라 utf-8, utf-16, utf-32 등으로 나뉨

     

     

    CPU 핵심 구성 요소

    ALU(산술논리연산장치) : 연산 수행하는 장치로 계산 담당함
    레지스터로부터 피연산자를 받아들이고, 제어장치로부터 제어 신호(연산할 작업) 받아들임
    = 연산 결과 값을 레지스터, 플래그 레지스터(연산 결과의 부가 정보)에 저장
    제어장치 : 명령어 해석 및 제어 신로 내보내는 장치
    명령어 레지스터와 플래그 레지스터로부터 정보를 받아 클럭 신호를 따라 명령어를 해석하고 필요한 장치로 제어 신호를 내보냄
    << 클럭 신호 : 부품의 동작 시간 단위 혹은 박자로 일정하지 않음 >>
    레지스터 : 명령어 처리 전후로 값을 임시 저장하는 장치 = 개발자 입장에서 가장 중요함
    레지스터에 어떤 값이 저장되는지만 관찰해도 프로그램의 가장 저수준의 흐름을 볼 수 있음

     

    레지스터 종류

    • 프로그램 카운터 : 메모리에서 가져올 명령어 주소 저장, 일반적으로 1씩 증가함
    • 명령어 레지스터 : 해석할 명령어 저장
    • 메모리 주소 레지스터 : 메모리의 주소 저장
    • 메모리 버퍼 레지스터 : 메모리와 주고받을 명령어와 데이터 저장
    • 플래스 레지스터 : 연산 결과에 대한 부가 정보 저장
    • 범용 레지스터 : 범용적으로 사용 가능한 레지스터 = 여러 개 있음
    • 스택 포인터 : 스택 주소 지정 방식에서 사용하며 스택의 꼭대기 가리킴
    • 베이스 레지스터 : 변위 주소 지정(상대 주소 지정) 방식에서 사용하며 떨어진 거리를 가리킴

     

    CPU 명령어 처리 : 기본적으로 인출 사이클과 실행 사이클을 거쳐 실행하며 간접 주소를 사용하는 등 추가 작업이 더 필요한 경우 간접 사이클 추가함

     

    인터럽트(interrupt) : CPU의 정상적인 실행 흐름을 방해하는 신호

    • 동기 인터럽트 (예외, Exception) : 주로 CPU에 의해 발생하며 명령어 처리 도중 비정상적인 상황에 마주했을 경우 발생
    • 비동기 인터럽트 (하드웨어 인터럽트) : 주로 입출력장치에 의해 발생하며 '알림' 역할 수행, 입출력장치가 작업을 수행하고 있는 중에 CPU에서 다른 작업이 수행될 수 있기 때문에 알림이 필요함

    하드웨어 인터럽트 처리 순서

    1. 입출력장치는 CPU에 인터럽트 요청 신호 전송
    2. CPU는 실행 사이클 이후 인출 전 인터럽트 여부 확인
    3. CPU는 인터럽트 요청 확인 후, 인터럽트 플래그를 통해 인터럽트 수용 여부 확인
    4. 인터럽트가 가능하다면 지금까지의 작업을 메모리 내 스택에 백업
    5. 인터럽트 벡터(인터럽트 서비스 루틴 종류 구분 정보)를 참고하여 인터럽트 서비스 루틴(인터럽트 핸들러) 실행
    6. 인터럽트 서비스 루틴 실행 후 백업한 작업 복구, 실행 재개

     

     

    CPU 오버클럭킹 : 임의로 클럭 속도를 끌어올리는 기술 (컴퓨터 부팅 시 BIOS에서 설정 가능)

    코어 : 명령어를 인출하고, 해석하고, 실행하는 CPU 내 부품 = 코어가 여러개 있으면 한 번에 여러 명령어 처리가 가능함

     

    스레드

    • 하드웨어에서의 스레드 : 하나의 코어가 동시에 처리하는 명령어 단위
    • 소프트웨어에서의 스레드 : 하나의 프로그램을 독립적으로 실행하는 단위

     

    멀티스레드 CPU : 여러 개의 스레드를 이용해 한 코어로 여러 명령어를 실행 가능한 CPU = 복수의 레지스터 세트 사용을 고려해야 함

     

    메모리와 프로그램은 스레드와 코어 구분이 불가능해서 각각의 스레드를 코어로 인식함
    ex. 2 코어 4 스레드 = 4 코어로 인식
    하드웨어 스레드는 논리 프로세서라고 부르기도 함

     

     

    명령어 파이프라이닝 : 명령어가 처리되는 서로 다른 단계를 동시에 처리하는 기법

    명령어는 필요한 처리 단계가 겹치지 않는다면 여러 개의 명령어를 한꺼번에 실행 가능함

     

    파이프라인 위험(pipeline hazard) : 명령어 파이프라이닝이 실패하는 경우 발생

    • 데이터 위험(data hazard) : 명령어 간 의존성에 의해 발생
    • 제어 위험(control hazard) : 프로그램 카운터의 갑작스러운 변화(분기)에 의해 발생
    • 구조적 위험(structural hazard) : 서로 다른 명령어가 같은 자원을 사용하려 할 경우 발생

    슈퍼스칼라 : 다수의 명령어 파이프라인을 두는 방식

     

    파이프라이닝을 활용하지 위한 CPU 구조

    CISC(Complex Instruction Set Computer) - Intel x86 CPU
    복잡하고 다양한 기능의 명령어와 다양한 주소 지정 방식을 제공하며 적은 명령어 수로 명령어 실행이 가능함

    일정하지 않은 클록 수로 인해 명령어 파이프라이닝에 불리함
    쓰이는 명령어만 반복적으로 사용되고 대부분의 명령어는 사용되지 않음
    [ 20%의 명령어가 사용되는 명령어의 80% 차지함 ]
    RISC(Reduced Instruction Set Computer) - ARM CPU
    짧고 규격화된 명령어로 명령어 파이프라이닝에 유리함
    적은 수의 명령어를 제공하며 레지스터를 활용해 메모리 접근을 최소화함

    CISC에 비해 더 많은 명령어로 실행되는 점 때문에 컴파일러의 역할이 중요함

     

    비순차적 명령어 처리(OoOE : Out-of-Order-Execution)

    파이프라이닝 내의 의존 관계가 없는 명령어를 순차적으로 처리하지 않는 방법

    명령어를 순차적으로 실행할 때 성능 향상에 실패할 수 있는 점을 고려해,

    순서를 바꿔도 프로그램 실행에 영향이 없는 명령어 순서를 바꿈으로써 파이프라이닝 성능을 높이는 기법

    [ 순서를 바꿔도 무방한 명령어를 구분하는 건 CPU가 해야 할 일 ]

    '프로그래밍 > CS' 카테고리의 다른 글

    운영체제 (2)  (0) 2024.08.31
    운영체제 (1)  (0) 2024.08.06
    컴퓨터 구조 (2)  (0) 2024.08.05
Designed by Tistory.