하드웨어의 한계를 넘어: 마이크로벤치마킹으로 디스크 물리적 구조 파헤치기
최근 Hacker News를 통해 흥미로운 2019년도의 글이 다시 조명을 받았습니다: “Discovering hard disk physical geometry through microbenchmarking"입니다. 고성능 SSD가 대중화된 시대에 회전형 매체(HDD)의 물리적 구조를 파악하는 일이 왜 중요할까요?
사실 이 글의 핵심은 단순한 하드디스크의 구조를 넘어, ‘관찰 가능한 성능(Observable Performance)‘을 통해 하드웨어의 내부 동작을 추론하는 방법론에 있습니다. 이는 최신 NVMe SSD의 ZNS(Zoned Namespace) 스토리지나 최근 논의되고 있는 LoRa 기반의 BYOMesh 같은 저전력 네트워크 장비의 성능 특성을 분석할 때도 적용 가능한 원리입니다.
이번 포스트에서는 직접 간단한 코드를 작성하여, 하드웨어의 ‘숨겨진 신체 측정(Physical Geometry)‘을 알아내는 마이크로벤치마킹 기법을 실습해 보겠습니다.
왜 마이크로벤치마킹인가?
소프트웨어 개발자는 OS와 하드웨어 사이의 추상화 계층 덕분에 복잡한 하드웨어 세부 사항을 몰라도 개발할 수 있습니다. 하지만 고성능을 요구하는 시스템, 예를 들어 고주문량을 처리하는 전자상거래 플랫폼이나 대용량 데이터를 처리하는 분석 시스템을 개발할 때는 이야기가 달라집니다.
운영체제가 제공하는 fstat나 lsblk 명령어만으로는 실제 섹터 배치나 캐시 메모리 크기, 회전 지연 시간 등을 정확히 알기 어렵습니다. 이때 직접 읽기/쓰기 작업을 수행하며 그 소요 시간을 측정하는 마이크로벤치마킹이 가장 강력한 도구가 됩니다.
벤치마킹의 기본 원리
하드디스크(HDD)의 데이터 접근 속도는 다음 세 가지 요소로 결정됩니다.
- 탐색 시간(Seek Time): 헤드가 해당 트랙으로 이동하는 시간 (물리적 이동)
- 회전 지연(Rotational Latency): 데이터가 있는 섹터가 헤드 아래로 회전해 올 때까지의 시간
- 전송 시간(Transfer Time): 실제 데이터를 읽는 시간
우리는 이 중 **‘탐색 시간’**에 집중할 것입니다. 헤드가 이동해야 하는 거리가 멀수록 시간이 오래 걸리므로, 인접한 섹터를 읽을 때와 멀리 떨어진 섹터를 읽을 때의 시간 차이를 측정하면 디스크의 물리적 배치(트랙과 실린더 구조)를 유추할 수 있습니다.
실습: Python으로 디스크 구조 탐색
이제 파이썬을 사용하여 랜덤 액세스와 순차 액세스의 성능 차이를 측정해 보겠습니다. 이 코드는 디스크의 ‘외곽(Outer Zone)‘과 ‘내곽(Innter Zone)’ 사이의 이동 비용을 측정하는 간단한 예제입니다.
주의: 이 스크립트는 실제 디스크 장치(
/dev/sdX등)에 접근하므로, 반드시 데이터가 없는 테스트용 디스크나 VM 환경에서 진행하세요. 잘못된 장치에 접근하면 데이터가 손상될 수 있습니다.
import os
import time
import sys
# 테스트할 디스크 경로 (VM이나 별도 테스트 디스크로 변경 필요)
# 예: Linux의 경우 '/dev/sdb', macOS의 경우 '/dev/rdisk2'
DISK_PATH = '/dev/sdb'
# 읽기 블록 크기 (4KB)
BLOCK_SIZE = 4096
# 측정 횟수
ITERATIONS = 1000
def benchmark_random_access(fd, size):
"""랜덤한 위치에 접근할 때의 성능 측정"""
total_bytes = os.path.getsize(DISK_PATH) if os.path.exists(DISK_PATH) else size
start_time = time.time()
for _ in range(ITERATIONS):
# 랜덤한 오프셋 계산 (블록 단위 정렬 유지)
offset = os.urandom(8)
offset_int = int.from_bytes(offset, 'big') % (total_bytes - BLOCK_SIZE)
aligned_offset = (offset_int // BLOCK_SIZE) * BLOCK_SIZE
os.lseek(fd, aligned_offset, os.SEEK_SET)
os.read(fd, BLOCK_SIZE)
end_time = time.time()
return (end_time - start_time) * 1000 # ms 변환
def benchmark_sequential_access(fd):
"""순차적인 위치에 접근할 때의 성능 측정"""
start_time = time.time()
for _ in range(ITERATIONS):
os.read(fd, BLOCK_SIZE)
end_time = time.time()
return (end_time - start_time) * 1000 # ms 변환
if __name__ == "__main__":
if not os.path.exists(DISK_PATH):
print(f"Error: {DISK_PATH} not found. Please update DISK_PATH.")
sys.exit(1)
print(f"Benchmarking {DISK_PATH}...")
try:
# 파일을 열되 버퍼링을 최소화하기 위해 O_DIRECT 플래그 사용 권장 (Linux)
# 여기서는 호환성을 위해 기본 모드로 진행하나 실제 하드웨어 접근 시에는 O_DIRECT가 필요함.
fd = os.open(DISK_PATH, os.O_RDONLY | os.O_SYNC)
print("1. Measuring Random Access (Simulating Head Seek)..." )
# 랜덤 액세스는 헤드가 계속 움직이므로 느림
random_time = benchmark_random_access(fd, 1024*1024*1024) # 1GB 가정
print(f" Random Access Time: {random_time:.2f} ms")
print("2. Measuring Sequential Access (Minimal Head Movement)...")
# 파일 포인터를 다시 처음으로
os.lseek(fd, 0, os.SEEK_SET)
sequential_time = benchmark_sequential_access(fd)
print(f" Sequential Access Time: {sequential_time:.2f} ms")
print("\n--- Analysis ---")
print(f"Performance Gap (Seek Cost): {random_time - sequential_time:.2f} ms")
print("The gap represents the time spent moving the disk head physically.")
os.close(fd)
except PermissionError:
print("Error: Permission denied. Try running with 'sudo'.")
except Exception as e:
print(f"Error: {e}")
결과 해석 및 활용
위 코드를 실행하면 랜덤 액세스가 순차 액세스보다 훨씬 느린 것을 확인할 수 있습니다. 이 ‘차이(Gap)‘가 바로 물리적 탐색(Seek)과 회전(Rotation)에 소요된 시간입니다.
만약 이 측정을 디스크의 시작 부분(외곽 트랙)과 끝 부분(내곽 트랙)에서 나누어 진행한다면, 디스크의 Zone Bit Recording(ZBR) 구조 때문에 외곽이 내곽보다 전송 속도가 빠르다는 것을 발견할 수도 있습니다. 과거에는 이를 이용해 데이터를 디스크의 앞부분에 배치하는 튜닝을 하기도 했습니다.
현대적 의의: SSD와 클라우드 시대에서의 교훈
비록 회전판 디스크가 예전 기술이 되어가고 있지만, **‘성능 측정을 통해 시스템의 내부를 이해한다’**는 원칙은 변하지 않습니다.
- SSD의 내부 병렬성: SSD는 내부적으로 여러 채널과 플레인(Plane)을 병렬로 운용합니다. 우리가 멀티스레드로 순차 읽기를 유도했을 때 성능이 급격히 상승한다면, 이는 내부 컨트롤러의 병렬 처리 능력을 추론할 수 있는 신호가 됩니다.
- Cloud Storage I/O: AWS나 Azure의 디스크 I/O 성능이 ‘Burst’ 후에 ‘Baseline’으로 떨어지는 현상을 마이크로벤치마킹으로 포착하여 비용 효율적인 아키텍처를 설계할 수 있습니다.
결론
Hacker News에서 다시 주목받은 ‘디스크 물리적 구조 발견’ 글은 우리에게 단순한 호기심을 넘어, 시스템의 성능 병목을 진단하는 가장 기본적인 자세를 일깨워 줍니다.
막연한 느낌으로 “디스크가 느린가 보다"라고 단정 짓기보다, 직접 간단한 스크립트를 돌려보며 **“어디서 왜 느린지”**를 데이터로 증명해 보는 것. 이것이 진정한 성능 튜닝의 첫걸음입니다.
오늘 포스트에서 작성해 본 벤치마킹 코드를 여러분의 개발 환경에서 한번 돌려보시기 바랍니다. 예상치 못한 하드웨어의 특성을 발견하고, 그것이 시스템 성능에 미치는 영향을 직접 관찰하는 것은 매우 흥미로운 경험이 될 것입니다.