오전 : 알고리즘, DMA
오후 : DMA 정리, 알고리즘 문제 정리, realloc 개선, 이더넷
저녁 : 이더넷 정리, CSAPP 11장, 발표준비
Worst-Fit Allocation in Operating Systems - GeeksforGeeks
CSAPP 책에는 나오지 않았지만, 혼자 공부하는 컴퓨터구조&운영체제에 나온 worst fit을 구현해봤다.
🤔 worst fit이란?
할당할 수 있는 가용 블록 중 가장 크기가 큰 블록에 할당하는 방식
이름은 worst fit이지만, 분할과 합쳐지면 생각보다 좋은 성능을 낸다.
/**
* @brief asize만큼 할당할 수 있는 free 블록을 찾는 함수. worst fit 알고리즘 사용
*
* @param asize 할당하려는 크기
* @return void* asize 크기를 할당할 수 있는 free 블록의 포인터. 적합한 블록을 찾지 못하면 NULL 반환
*/
static void *worst_fit(size_t asize)
{
void *bp;
void *worst = NULL;
for (bp = heap_listp; GET_SIZE(HDRP(bp)) > 0; bp = NEXT_BLKP(bp))
{
if (!GET_ALLOC(HDRP(bp)) && GET_SIZE(HDRP(bp)) >= asize)
{
if (worst == NULL)
{
worst = bp;
continue;
}
if (GET_SIZE(worst) < GET_SIZE(bp))
{
worst = bp;
}
}
}
return worst;
}
위 블로그를 참고해서 개선된 realloc을 적용하면 맥북에서도 80점이 넘는 점수를 얻을 수 있다고 한다.
하지만 내가 적용해본 결과 explicit에서는 error가 발생하고, implicit에서는 60~62점 정도가 나온다… 🥺 (왜지… 왤까…)
기존 내 코드가 비효율적인가?????
그래도 오르긴 올랐으니까 분석해보자
void *mm_realloc(void *ptr, size_t size)
{
void *oldptr = ptr;
void *newptr;
size_t originsize = GET_SIZE(HDRP(oldptr)); // 기존에 할당된 크기
size_t newsize = size + DSIZE; // 새롭게 할당 요청 받은 크기
/* 새로 요청받은 크기가 기존 크기보다 작은 경우 */
if (newsize <= originsize)
{
return oldptr;
}
else
{
size_t addsize = originsize + GET_SIZE(HDRP(NEXT_BLKP(oldptr))); // 기존 블록의 크기 + 다음 블록의 크기
/* 다음 블록이 가용 블록이고 현재 블록과 연결했을 때 요청받은 크기를 수용할 수 있는 경우 */
if (!GET_ALLOC(HDRP(NEXT_BLKP(oldptr))) && (newsize <= addsize))
{
/* coalesce */
PUT(HDRP(oldptr), PACK(addsize, 1));
PUT(FTRP(oldptr), PACK(addsize, 1));
return oldptr;
}
else
{
/* 새로운 블록 할당하고 반환 */
newptr = mm_malloc(newsize);
if (newptr == NULL)
return NULL;
memmove(newptr, oldptr, newsize);
mm_free(oldptr);
return newptr;
}
}
}
implicit + next fit + improved realloc
Team Name:Team 4
Member 1 :Kang Bada:gangbada890@gmail.com
Using default tracefiles in ./traces/
Perf index = 45 (util) + 14 (thru) = 60/100
implicit + worst fit + improved realloc
Team Name:Team 4
Member 1 :Kang Bada:gangbada890@gmail.com
Using default tracefiles in ./traces/
Perf index = 48 (util) + 14 (thru) = 62/100
컴퓨터와 입출력장치 사이에서 데이터가 오가는 방식을 입출력 제어방식이라고 한다.
입출력 제어방식의 종류
제어방식 | CPU 관여 여부 |
---|---|
프로그램에 의한 I/O (PIO) | ⭕️ |
Interrupt에 의한 I/O | ⭕️ |
DMA에 의한 I/O | ❌ |
Channel에 의한 I/O | ❌ |
동작 순서
단점
I/O 장치는 매우 느리고, 대기하면서 특별한 일을 하는 것도 아니다!
이처럼 PIO 방식은 매우 비효율적이다.
🤔 Direct Memory Access란?
직역하자면 직접 메모리 접근이라는 뜻으로,
특정 하드웨어 장치가 CPU와 독립적으로 메인 메모리에 접근할 수 있게 해주는 컴퓨터 시스템의 기능이다.
PIO와 반대되는 개념으로 데이터가 CPU를 거치지 않는다.
대신, 입출력장치가 직접 메모리에 접근하여 data block을 읽고 쓸 수 있다.
동작 순서
CPU → DMA Controller 정보
import sys
input = sys.stdin.readline
n = int(input())
# dp 테이블 선언 (행: 0 ~ N / 열: 0 ~ 9)
# 행: 계단 수의 길이 / 열: 1의 자리 숫자
dp = [[0] * (10) for _ in range(n+1)]
# 길이가 1인 경우 1로 초기화
# 0은 1로 초기화하면 안 된다. (0으로 시작하는 숫자는 계단 수가 아님)
for i in range(1, 10):
dp[1][i] = 1
# dp 테이블 채우기
# 점화식: dp[n][k] = dp[n-1][k-1] + dp[n-1][k+1]
# 예외: k가 0 또는 9일 때
for i in range(2, n+1):
for k in range(10):
if k == 0:
dp[i][k] = dp[i-1][k+1]
elif k == 9:
dp[i][k] = dp[i-1][k-1]
else:
dp[i][k] = dp[i-1][k-1] + dp[i-1][k+1]
# 정답을 1,000,000,000으로 나눈 나머지 출력
print(sum(dp[-1]) % 1000000000)