我的操作系统背景不强,有人可以提供一些例子(如果可能请在Go中),为什么使用缓冲区很重要?
答案 0 :(得分:6)
假设您正在谈论IO:
想象一下,你有一个var fin *os.File
并且该文件包含在缓冲区var instrm *bufio.Reader
中。现在假设您正在编写某种解析器,一次读取输入的一个字符(比如说字节)。包bufio实现缓冲的I / O.
如果你拨打myParser.Parse(fin)
,你会拨打.Read
4,194,304次来读取每个字节,这将使系统调用4,194,304次,这将导致4,194,304 context switches。 context switches是控制从用户空间程序转移到OS并且是最慢(非IO)操作之一。在操作系统没有合并/预取IO请求的情况下,您的IO设备一次寻找和读取一个字节的可能性很大,但大多数操作系统IO elevator,预取和{{3现在阻止这种情况(但是在大型连续批次中读取总是更好)。
如果您使用默认myParser.Parse(instrm)
缓冲区为4K来调用bufio.Reader
,则会导致1,024个上下文切换(每个系统调用读取4K而不是1个字节)。由于每个系统调用都有一些开销,这意味着系统调用花费的时间更少,程序运行的时间更长。值得指出的是,以这种方式运行(没有额外的上下文切换)通常会增加device-side buffers缓存命中率,因为将花费更多时间CPU instruction。
缓冲区在网络IO等领域甚至非常重要,因为它允许您以最大branching within a smaller region of memory大小发送突发数据包,而不是发送一小撮微小数据包。
不要忘记刷新写缓冲区。