[공부 노트] #9

4 minute read

서브넷 마스크

주어진 네트워크 주소를 나누어 ip주소 자원을 효율적으로 사용하는 것을 서브넷이라고 하고, 이 때 네트워크 주소 부분을 식별하기 위한 것이 서브넷 마스크이다.

192.168.0.0/24

위의 네트워크를 서브넷마다 60개의 호스트가 존재할 수 있도록 서브넷팅을 한다면 60 <= $2^6$ 이므로 각 호스트 주소는 6비트의 공간이 필요하기 때문에

  • 192.168.0.0/26
  • 192.168.64.0/26
  • 192.168.128.0/26
  • 192.168.192.0/26

위의 경우로 서브넷팅 할 수 있겠다. 보통 네트워크의 최하위주소는 네트워크 주소로, 최상위 주소는 브로드캐스트 주소로 사용되므로 6비트의 공간을 사용하더라도 호스트는 최대 60(62 - 2)개가 할당될 수 있다.

http response

HTTP 상태 코드(HTTP status code)
상태 코드의 종류가 매우 많아서, 분류마다 몇 가지만 추려서 정리하였다.

  • 100 - 199 : 정보성 상태 코드
  • 200 - 299 : 성공 상태 코드
    • 200 : 정상적인 요청이며, 본문은 요청된 리소스를 포함한다
    • 204 : 정상적인 요청인데 제공할 내용은 없다
  • 300 - 399 : 리다이렉션 상태 코드, 요청에 대해 적절한 다른 위치를 제공하거나, 대안의 응답을 제공.
    • 303 : 요청받은 행동 수행을 위해서는 다른 URL로 요청 해야한다
    • 304 : 이전의 동일한 요청과 비교하여 변화가 없다
  • 400 - 499 : 클라이언트 에러 상태 코드
    • 400 : 클라이언트가 올바르지 못한 요청을 보내고 있다
    • 401 : 요청을 위해서는 권한 인증이 요구된다
    • 403 : 요청이 서버에 의해 거부 되었다(forbidden)
    • 404 : 요청한 URL을 찾을 수 없다(page not found)
  • 500 - 599 : 서버 에러 상태 코드
    • 500 : 서버에 오류가 발생하여 응답 할 수 없다
    • 504 : 서버에서 다른 서버로 요청을 보냈으나, 응답 지연이 발생하여 처리가 불가하다

파이프라이닝

파이프라인(파이프라이닝)이란 cpu의 처리량을 개선하기위해 연산을 여러 단계로 나누어 동시에 처리하는 것을 의미한다.
컴퓨터구조 수업에서는 MIPS를 배웠는데, MIPS의 명령어 실행은 5단계로 나뉜다.

  1. IF(Instruction Fetch) : 명령어를 메모리에서 가져온다
  2. ID(Instruction Decode) : 명령어를 해독하고 레지스터를 읽는다
  3. EX(Excution) : ALU로 연산을 진행한다
  4. MEM(Data Memory Access) : 데이터 메모리에 있는 피연산자에 접근한다
  5. WB(Write Back) : 결과값을 레지스터에 쓴다

파이프라인 해저드
수행되는 파이프라인이 지연/중단되는 현상을 말한다.

  • 구조적 해저드 : 자원 충돌
    • 예를들어, 포트가 하나인 메모리에 동시에 접근하려고 하거나 ALU 등의 하드웨어를 동시에 사용하려는 경우.
    • 하드웨어 자원을 추가하거나 버블 추가
  • 데이터 해저드 : 미수행된 명령의 결과값 참조(즉, 동기화문제)
    • 쓰기 후 읽기, 읽기 후 쓰기 , 쓰기 후 쓰기의 경우
    • 전방 전달: MUX를 추가하여 값을 전달해주기
    • 클락을 쪼개서 1/2 단계에서는 쓰고 2/2 단계에서는 읽기
    • 프로그램 실행에 영향이 없다면 실행 순서를 변경
  • 제어 해저드 : 조건 분기로 순서가 변경되어 명령어가 무효화
    • 분기문과 상관없는 명령어를 분기문 뒤에 배치하고, 분기 결과가 나오면 분기문 흐름으로 돌아감
    • 분기가 무조건 일어나지 않는다고 가정하고 수행한뒤, 만약 분기가 일어나면 수행한 명령어를 flush
    • 하드웨어를 추가하여 분기 결과를 MEM단계가 아닌 ID단계에서 판별
    • 분기 예측 버퍼나 분기 히스토리 테이블을 이용해서 분기 결과를 예측하여 명령어를 패치

for문 cache

for (i = 0; i < columns; i += 1) {
  for (j = 0; j < rows; j += 1) {
    arr[j][i] = pow(arr[j][i]);
  }
}

2차원 배열의 모든 요소를 제곱하는 반복문인데, 자세히 살펴보면 연속적으로 저장된 배열의 값에 순차적으로 접근하고 있지 않아서 공간 지역성 측면에서 비효율적이므로

for (i = 0; i < rows; i += 1) {
  for (j = 0; j < columns; j += 1) {
    arr[i][j] = pow(arr[i][j]);
  }
}

로 바꿀 수 있다.

for (i = 0; i < n; i += 1) {
  for (j = 0; j < arr.size(); j += 1) {
    arr[j] = pow(arr[j]);
  }
}

배열 arr의 모든 원소를 n번 제곱하는 코드이다. 전체 데이터가 캐시보다 크다면, 반복문의 초기에 캐시에 쓴 값들은 후기에 덮어쓰여지고, 다음 반복문의 초기에 활용하지 못하고 다시 캐싱해야한다.(사실 한 번 접근했을 때 n번 제곱하도록 반복문의 순서를 바꾸면 되지만, 설명을 위한 코드이므로 넘어가자)
이 때 배열 순회 주기를 캐시의 크기만큼으로 해준다면 시간 지역성 측면에서 효율적으로 개선할 수 있다.

for (i = 0; i < arr.size(); i += CACHE_SIZE) {
  for (j = 0; j < n; j += 1) {
    for (k = 0; k < CACHE_SIZE; k += 1) {
      arr[i + k] = pow(arr[i + k]);
    }
  }
}

프로세스에 할당되는 메모리의 각 영역.

(낮은 주소 순서)

  • 코드(텍스트) 영역 : 컴파일한 기계어가 저장되어있는 읽기 전용 영역
  • 데이터 영역 (BSS, GVAR) : 프로그램이 실행될 때 생성되는 전역 변수, 정적 변수, 배열, 구조체 등.
    • 초기화된 데이터는 GVAR, 그렇지 않으면 BSS영역에 저장
  • 힙 영역 : 필요에 의해 메모리를 동적으로 할당하여 사용하는 영역
  • 스택 영역 : 함수 호출시 생성되어 지역변수, 매개변수가 저장되고, 함수가 끝나면 반환된다.

페이지와 세그멘테이션

페이지
프로세스가 사용하는 메모리공간이 연속적이어야한다는 제약을 없애기 위한 메모리 관리기법. 프레임이라는 고정된 단위로 메모리공간을 나누고, 프로세스에 할당해준다. 프로세스는 논리메모리를 가지고, 이 논리메모리를 물리메모리에 매핑하므로 물리메모리가 연속적일 필요가 없이 적절한 프레임에 할당하는 것이 가능하다. 이 때, 프레임이 고정된 크기라서 프로세스가 요구하는 메모리가 프레임 크기의 정수배가 아니라면 마지막 프레임은 공간이 남는 내부 단편화 문제가 발생한다. 이것을 줄이기 위해서 프레임의 크기를 줄이면 그만큼 매핑하는 과정이 늘어나는 비효율이 발생한다.

세그멘테이션 메모리공간을 세그먼트라는 다양한 크기의 단위로 나눈다. 적절한 크기의 세그먼트를 사용해서 프로세스에 할당해주면 내부단편화 문제를 해결할 수 있으나, 메모리가 할당되고 해제되는 과정이 반복되면 결국 사용하지 못하는 작은 부분들이 많아져서 외부단편화 문제가 심화된다.
따라서 세그멘테이션으로 메모리공간을 나누고 그 공간을 다시 페이징기법을 통해 나누면 단편화 측면에서 효과가 높지만, 페이지테이블과 세그멘테이션테이블을 모두 접근해야하므로 속도면에서는 손해이다.

메모리 배치 알고리즘

  • First Fit : 할당할 수 있는 첫 번째 공간을 할당
    • 간단하며, 빠르게 할당할 수 있다.
  • Best Fit : 할당할 수 있는 공간 중 가장 작은 공간을 할당
    • 큰 공간을 쪼개지 않을 수 있지만, 가장 작은 단편들을 만들어내어 외부 단편화를 심화시킨다
  • Worst Fit : 할당할 수 있는 공간 중 가장 큰 공간을 할당

페이지 교체 알고리즘

  • FIFO : 가장 먼저 들어온(가장 오래된) 페이지를 교체
  • LRU(Least Recently Used) : 사용된지 가장 오래된 페이지를 교체
  • NUR(Not Used Recently) : 최근에 사용하지 않은 페이지 중 하나를 교체
    • LRU를 근사하는 방식으로, 구현 비용에서 이득
    • Stack이나 Counter가 필요한 LRU에 비해 참조비트, 변형비트를 사용하여 오버 헤드가 적음
  • LFU(Least Frequently Used) : 사용 빈도가 가장 적은 페이지를 교체
  • OPT : 가장 오랫동안 사용되지 않을 페이지를 교체
    • 미래 정보를 알 수 없으므로 구현 불가능

참고문헌

https://velog.io/@honeysuckle/HTTP-%EC%83%81%ED%83%9C-%EC%BD%94%EB%93%9C-HTTP-status-code-
https://blog.naver.com/PostView.nhn?blogId=megatrue&logNo=220773628357
https://blog.naver.com/PostView.nhn?blogId=icbanq&logNo=221683960935
https://parksb.github.io/article/29.html

Leave a comment