[Chapter 2] Instructions: Language of the Computer_3

slchoi·2022년 1월 4일
0

컴퓨터구조

목록 보기
6/15
post-thumbnail

KOCW에 공개된 영남대 최규상 교수님 컴퓨터구조 강의를 수강 후 정리한 내용입니다.

2.14 Arrays versus Pointers


1. Arrays vs Pointers

  • array를 사용할 경우 항상 array의 인덱스를 계산하기 위해 인텍스에 element size를 곱해주는 연산 + 곱한 값에 array base address를 더해주는 연산이 필요
  • pointer를 사용할 경우 바로 memory adress로 접근 가능. index를 계산하는 과정이 필요없게 됨
  • pointer를 사용하는 것이 성능이 더 향상될 수 있음

Example: Clearing and Array

  • 두 함수는 같은 일을 수행. array의 모든 값을 0으로 초기화해줌
    • 왼쪽 코드는 array, 오른쪽 코드는 pointer를 사용
    • $a0: array의 시작 주소, $a1: size
  • 오른쪽 코드에서
    • addi $t0, $t0, 4: $t0에 4를 더해줌. 다음 element 시작 주소 값으로 변경해주는 과정
    • $t2: array[size]의 시작 주소
  • array를 사용할 경우 loop 안의 명령어 개수는 6개, pointer를 사용할 경우 loop 안의 명령어 개수는 4개로 구성
    • loop의 반복이 많은 경우 pointer로 구현하는 것이 더 높은 성능을 보임

2. Comparison of Array vs Pointer

  • 컴파일러는 포인터를 사용하는 것과 같은 비슷한 효과를 줄 수 있음
    • Induction variable elimination: 인덱스 사용하는 것을 없애줌
  • 컴파일러를 사용해 array 방식으로 프로그램을 구성하면 훨씬 이해하기 쉽고 버그가 생길 확률이 줄어듦
  • pointer을 사용할 경우 버그가 생길 확률이 높기 때문에 일반적으로 프로그램을 구성할 때는 array를 사용하는 것을 권장

2.16 Real Stuff: ARM Instructions


Compare and Branch in ARM

  • arithmetic/logical instruction의 결과에 따라 조건문을 만들 수 있음
  • 각각의 명령어가 조건이 될 수 있음
    • instruction word의 top 4 bits를 condition value로 채움
    • 하나의 명령어로 구성된 branch를 회피할 수 있음

2.17 Real Stuff: x86 Instructions


  • Intel CPU와 MIPS의 차이
    • x86은 레지스터마다 길이가 다름
    • operand에 메모리 주소를 바로 쓸 수 있음. MIPS는 load/store을 제외하고 명령어들이 메모리를 직접적으로 access하지 않음(레지스터 사이에서 연산 수행)
    • MIPS는 명령어의 길이가 32bit로 고정. x86은 명령어의 길이가 다양함

Implementing IA-32

  • MIPS: Reduced Instruction set(RISC)
  • Intel의 아키텍쳐: Complex instruction set(CISC)
    • implementation이 까다롭고 높은 성능을 보이기 어려움
    • 해결 방법
      • 하드웨어가 하나의 명령어를 간단한 suboperaions(microoperations)으로 나눔. 하나의 명령어가 여러 개의 명령어로 나눠지게 됨
      • Microengine은 microoperation을 실행하는데 이 때 Microengine이 RISC와 유사해 성능을 낼 수 있었음
      • 겉으로는 CISC이지만 내부적으로는 RISC
  • Intel은 구조적으로는 MIPS에 비해 안 좋은 구조를 가지지만, 내부적으로는 MIPS와 같은 RISC 아키텍쳐를 따르기 때문에 CISC 명령어를 microoperations으로 나눠주는 오버헤드를 제외하면 내부적인 성능은 비슷

2.19 Fallacies and Pitfalls


1. Fallacies

  1. Powerful instruction(하나의 명령어가 여러 개의 일을 한 번에 처리하는 것)을 사용하면 높은 성능을 보여줄 것

    • 이유: 명령어의 수가 줄기 때문
    • 실제로는 복잡한 명령어는 구현하기 어렵기 때문에 컴파일러는 powerful instruction보다 간단한 명령어 여러 개를 사용해서 만든 코드가 더 높은 성능을 보임
  2. 어셈블리 코드를 사용하면 높은 성능을 보여줌

    • 실제로 높은 성능을 보일 순 있지만 최근의 컴파일러는 C언어로 작성한 코드도 어셈블리어로 작성한 코드와 유사한 성능을 보여줌
    • 어셈블리 코드를 사용할 경우 line 수가 증가하기 때문에 더 많은 에러가 발생할 수 있고 생산성이 떨어짐. 따라서 특수한 경우(ex. 임베디드)를 제외하고는 high-level language를 사용하는 것이 좋음
  3. Backward compatibility(예전 것이 새로운 환경에서도 지원이 되는 것)을 지원한다는 것이 instruction set이 바뀌지 않는다는 것을 의미

    • instruction set이 바뀌지 않는다는 것을 의미하는 것은 아님
    • instruction set는 계속 변경되지만 예전에 지원한 instruction이 현재에도 지원되기 때문에 backward compatibility를 보장

2. Pitfalls

  1. Sequential words는 sequential addresses가 아님

    • word의 크기는 4byte이므로 주소가 1이 아닌 4씩 증가
  2. procedure 내에서 전역 변수를 가리키는 포인터를 사용했을 때 포인터가 함수가 끝난 후면 포인터가 가리키는 메모리 주소는 유효한 메모리 주소가 아니게 됨

    • stack에서 pop될 때 포인터는 유효한 메모리 주소를 가리키지 않음
    • 함수 내에서 정의한 포인터는 함수 내부에서만 사용해야 함

2.20 Concluding Remarks


1. Design principles

  1. Simplicity favors regularity
  2. Smaller is faster
  3. Make the common case fasst
  4. Good design demands good compromises

2. Layers of software/hardware

  • Compiler, assembler, hardware
  • 프로그램이 어떻게 실행 파일이 되고 실행 파일이 어떻게 실행되는지

3. MIPS: typical of RISC ISAs

  • cf) x86: typical of CISC
  • MIPS는 benchmark 프로그램
    • Consider making the common case fast
      • Integer의 경우 Data transfer과 Condition Branch를 빠르게 하는 것이 중요
      • Floating point의 경우 Arithmetic과 Data transfer를 빠르게 하는 것이 중요

5주차 끝!!!
게시물에 사용된 사진은 강의 내용을 캡쳐한 것입니다.

profile
예비 백엔드 개발자

0개의 댓글