1
$\begingroup$

I read the lecture 4 of CS162 (UC Berkeley: https://inst.eecs.berkeley.edu/~cs162/sp17/static/lectures/4.pdf), but I got little bit confused about the meaning of the keyword "buffered" they used when mentioning the following informations:

Kernel buffered reads

Kernel buffered writes

Data buffered automatically by C-library functions

What does each of 'buffering' and 'buffered' mean?

$\endgroup$
4
$\begingroup$

When reading from a source, often a program wants to read data a few bytes at a time. For instance, the program can ask the OS for the next 4 bytes from a file, so to read the next 32-bit integer. Then, it can repeat the operation again and again, until all the integers have been read.

However, that is rather inefficient. First, disk (or even SSD) reads are done in hardware using large chunks, only, like 512 or more bytes. Reading that much only for 4 bytes is a waste of band. Second, switching between user mode and kernel mode has its cost, and it would be better if any such switch would transfer a non-trivial amount of data.

For that reason, reading is usually done in large chunks, using a "buffer". Basically, the OS reads a large-ish portion of the file (say, a few KBs), and keeps this in a kernel-space array (the "buffer"). This is done in one large chunk so to optimize disk/SSD access. After this, when the program asks for the next bytes, the OS does not need to involve the hardware, and can return data from the buffer.

Context switches are similarly optimized. The C library also commonly reads a large chunk form the OS, using a user-space buffer, using only one system call (= one switch). In this way, when the application program asks for the next (say) 4 bytes, the C library can copy from the buffer without making system calls.

When the buffer becomes empty, the C library starts asking again to the OS, and the OS starts asking again to the hardware.

Buffered writing is similar, but in the other direction, converting many small writes to fewer big ones, so to improve performance. This is done by the C library and the OS/kernel.

$\endgroup$
  • $\begingroup$ Thanks for the explanation. But I didn't understand how small writes can be done by kernel while the buffer array doesn't get filled in the end?? $\endgroup$ – Kais Jan 1 '18 at 23:10
  • $\begingroup$ @Kais Can you be more specific? I'm not sure I understand the issue. Anyway, usually the kernel stores small writes until the buffer becomes full OR a certain time has elapsed, after which a hardware write is done. The exact kernel buffering strategy may vary. $\endgroup$ – chi Jan 1 '18 at 23:18
  • $\begingroup$ ok. I mean when my program used to call "fputc('9', f)" in order to just write the char '9' to text file 'f'. Let's say the libc internal buffer is sized to 10kb(>char size). In this case how does the libc perform the i/o syscall while its buffer is not yet filled? $\endgroup$ – Kais Jan 1 '18 at 23:32
  • $\begingroup$ @Kais It does not. Libc waits for the buffer to fill, or for the program to call fflush on stdout (or file close). Only at that time the syscall is done. This means that after your fputc other concurrent processes might not see the 9 in the file, yet -- only after the flush it will be actually written. $\endgroup$ – chi Jan 1 '18 at 23:57
  • $\begingroup$ Ah. It is very clear now. Thanks man :) $\endgroup$ – Kais Jan 2 '18 at 0:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.