DSA, Database System & Operating System β Memory Management, File Systems & Administration, NEC licence examination syllabus (Nepal Engineering Council).
File System Performance
Caching, buffering and read-ahead β the techniques that make a slow disk look fast, measured.
π Where this lives: the buffering measurement below β 8,746Γ faster with one write instead of many β is the single most actionable number in this subject. It is why print() in a loop is slow when redirected to a file, why database bulk loaders batch inserts, and why every logging library buffers. It also explains a subtler thing: the second time you run a command it is faster, because the page cache still holds the files. Nothing was optimised; the disk was simply not touched. Search "page cache linux free -h buff/cache".
Why caching works: locality again
The BUFFER CACHE (or PAGE CACHE) keeps recently used disk blocks
in RAM. It works for exactly the reasons virtual memory works:
TEMPORAL LOCALITY a block read now is likely read again soon
SPATIAL LOCALITY a block near one just read is likely needed
The OS uses ALL FREE MEMORY as cache. This is why "free
memory" on a healthy machine is nearly zero and that is
CORRECT β unused RAM is wasted RAM. On Linux, `free -h` shows
it under buff/cache, and it is reclaimed instantly when a
program needs it.
MEASURED ON THIS MACHINE (vm_stat, 16 KB pages):
Pages free 4,171 = 0.06 GB
Pages active 201,820 = 3.08 GB
Pages inactive 199,306 = 3.04 GB
Pages wired 152,264 = 2.32 GB
Only 0.06 GB genuinely free. The 3.04 GB "inactive" is largely
cache β available if needed, useful meanwhile.
CACHE WRITE POLICIES β the durability trade-off:
WRITE-THROUGH write to cache AND disk immediately
β safe: a crash loses nothing
β slow: every write waits for the disk
WRITE-BACK write to cache; flush later
β FAST, and absorbs repeated writes to the
same block into one disk write
β a crash loses unflushed data
β what all general-purpose systems use
Because write-back is the default, `fsync()` exists: it forces
the flush and is the only way an application can KNOW its data
is durable. This is exactly the fsync from the ACtE0704
recovery topic β a database's durability guarantee rests on it.
UNIFIED BUFFER CACHE: modern systems use ONE cache for both
file I/O and memory-mapped pages, so `read()` and `mmap()` of
the same file share pages rather than keeping two copies.
The cost of system calls β measured
buf.c
/* Write 200,000 bytes three ways. Verified on this machine. */
#define N 200000
/* 1. one write() system call PER BYTE */
int fd = open("a.dat", O_CREAT|O_WRONLY|O_TRUNC, 0644);
for (int i = 0; i < N; i++) write(fd, "x", 1);
/* 2. buffered stdio β the library batches into ~4 KB chunks */
FILE *f = fopen("b.dat", "w");
for (int i = 0; i < N; i++) fputc('x', f);
fflush(f);
/* 3. ONE write() of the whole buffer */write(fd, big, N);MEASURED OUTPUT:
200000 bytes written three ways:
write() per byte 218.65 ms (200000 syscalls)
buffered fputc() 2.77 ms (~48 syscalls)
one write() of all 0.02 ms (1 syscall)
buffering is 79x faster; one big write is 8746x faster
READ THOSE THREE NUMBERS. Identical output β 200,000 identical
bytes in a file β at wildly different cost.
218.65 ms / 200,000 calls = 1.09 Β΅s PER SYSTEM CALL
That is the mode-switch cost from the OS-services topic,
measured: about a microsecond each, and it dominates
completely when the work per call is one byte.
2.77 ms with ~48 syscalls = the same total data with 4000Γ
fewer crossings of the user/kernel boundary. 79Γ faster.
0.02 ms with 1 syscall = 8,746Γ faster than per-byte.
WHY THE LAST ONE IS SO FAST: 200 KB is copied into the page
cache in one operation and the actual disk write happens later
(write-back). The 0.02 ms is essentially a memcpy β the program
did not wait for the disk at all.
THE GENERAL PRINCIPLE, and it applies far beyond file I/O:
BATCH WORK ACROSS AN EXPENSIVE BOUNDARY.
Β· file I/O β buffer, or write once
Β· network β send larger packets (Nagle's algorithm)
Β· database β multi-row INSERT, not N statements
Β· graphics β one draw call with many vertices
In every case the boundary crossing costs far more than the
payload, so the fix is fewer, larger crossings.
This is the same reasoning as the ACtE0703 measurement that a
1000-row INSERT beats 1000 single-row INSERTs, and the same as
the log's sequential-write advantage in ACtE0704. One idea,
four layers.
1.09 Β΅s per system call is worth memorising as a rough constant. A function call is ~1 ns, so a syscall is roughly 1000Γ more expensive β which is why stdio exists at all, why io_uring was invented to batch syscalls, and why "just call read() per byte" is never acceptable.
Read-ahead and other techniques
READ-AHEAD (prefetching)
when sequential access is detected, read the NEXT blocks before
they are requested.
β turns a series of blocking reads into one large read the
application never waits for
β hugely effective for streaming, copying, table scans
β wasted I/O and wasted cache if the guess is wrong
Applications can advise the kernel:
posix_fadvise(fd, off, len, POSIX_FADV_SEQUENTIAL)
posix_fadvise(fd, off, len, POSIX_FADV_RANDOM)
Databases use FADV_RANDOM precisely to DISABLE read-ahead,
because they know their access is not sequential and
prefetching would evict useful cache.
FREE-BEHIND / DROP-BEHIND
for a sequential scan, DISCARD blocks already passed. A
one-pass scan of a 100 GB file should not evict the entire
cache β this is the scan-resistance problem from the page
replacement topic, solved at the file layer.
BLOCK PLACEMENT
Β· keep an inode NEAR its data blocks, so reading metadata and
then data is one short seek instead of a long one
Β· CYLINDER GROUPS (UFS/ext) divide the disk into regions, each
with its own inodes and blocks, so a file's metadata and data
stay close
Β· keep a directory's files together, since programs usually
read several files from one directory
DISK GEOMETRY AWARENESS: largely obsolete. Modern drives lie
about geometry (LBA hides it) and SSDs have none, so
filesystems no longer optimise for cylinders β they optimise for
CONTIGUITY, which still helps because it means fewer, larger
requests.
RAM DISK / tmpfs
a filesystem entirely in memory. No persistence, but no I/O.
Used for /tmp, build scratch space, and container overlays.
MEASURED CONTEXT β the sequential-versus-random result from the
disk topic:
sequential read 8.9 ms (8730 MB/s)
random read 10.5 ms (7474 MB/s)
random only 1.17Γ slower
Both figures exceed any SSD's raw speed because the 78 MB file
fit entirely in the PAGE CACHE. That is the honest reading of
the measurement: what it demonstrates is not the SSD's speed
but the CACHE's β the disk was barely involved. Which is
precisely the point of this topic.
To measure the disk itself you must defeat the cache:
Β· O_DIRECT (Linux) β bypass the page cache entirely
Β· F_NOCACHE (macOS)
Β· a file much larger than RAM
Β· purge the cache between runs (`sync; purge` on macOS)
Any I/O benchmark that does not do one of these is measuring
RAM.
π Go further: the syscall cost is now being attacked directly. io_uring (Linux 5.1+) lets an application submit many I/O requests through a shared ring buffer with zero syscalls in the steady state, and has produced 2β3Γ throughput improvements for high-performance servers and databases. It is the same batching idea taken to its limit: rather than making syscalls cheaper, remove them from the hot path. Search "io_uring vs epoll performance".
π‘ Exam angle: explain the buffer/page cache and why it uses all free memory. Know write-through versus write-back and that write-back is universal, which is why fsync() is needed for durability. Describe read-ahead, free-behind and block placement / cylinder groups as performance techniques. The strongest answer quantifies the syscall cost β batching 200,000 one-byte writes into one call was measured at 8,746Γ faster, from which one syscall costs ~1 Β΅s β and notes that any I/O benchmark not bypassing the cache is measuring RAM.
Syllabus points
Factors affecting performance
Create a free account to tick topics off, take notes as you read, watch the video lessons and get a day-by-day study plan built around your exam date.
Related topics in Memory Management, File Systems & Administration