입출력 버퍼링 문서의 검증 코드다. if __name__ == "__main__": 아래가 자체 테스트다.
"""입출력 버퍼링의 블록당 시간 (Stallings 11.4절).
T: 장치에서 블록 하나를 읽는 시간, C: 프로세스가 블록 하나를 계산하는 시간, M: 버퍼에서 사용자 공간으로 옮기는 시간.
버퍼 없음: T + C, 단일 버퍼: max(C, T) + M, 이중 버퍼: max(C, T) (M은 무시할 만큼 작다고 둠)."""
def per_block(T, C, M=0.0):
return {"none": T + C, "single": max(C, T) + M, "double": max(C, T)}
def simulate(kind, T, C, M, n=1000):
"""블록 n개를 처리하는 데 걸리는 시간을 단계별로 흉내 낸다 (정상 상태 확인용)."""
if kind == "none":
return n * (T + C)
if kind == "single":
# 읽기(T) -> 옮기기(M) -> [계산(C) 동안 다음 읽기(T)] 반복
return T + M + (n - 1) * (max(C, T) + M) + C
# double: 한 버퍼를 계산하는 동안 다른 버퍼를 채운다
return T + (n - 1) * max(C, T) + C
if __name__ == "__main__":
for T, C, M in [(10, 4, 1), (5, 8, 1), (6, 6, 0.5)]:
p = per_block(T, C, M)
for k in ("none", "single", "double"):
avg = simulate(k, T, C, M) / 1000
exp = p[k] if k != "double" else max(C, T)
assert abs(avg - exp) < 0.05 * exp, (T, C, M, k, avg, exp)
# 카드: T = 10, C = 4, M = 1 -> 14, 11, 10
assert per_block(10, 4, 1) == {"none": 14, "single": 11, "double": 10}
assert per_block(5, 8, 1) == {"none": 13, "single": 9, "double": 8} # 카드 C1
# 이중 버퍼에서 C > T면 프로세스가, T > C면 장치가 병목
assert per_block(5, 8)["double"] == 8 and per_block(10, 4)["double"] == 10
print("ALL CHECKS PASSED")