From 68381eaae0301e8b49030be60631441cc7a1689a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E5=A4=A7=E4=BB=99?= <1900919313@qq.com> Date: Fri, 18 Oct 2024 17:40:18 +0800 Subject: [PATCH] c --- docs/notes/01_c-basic/07_xdx/assets/10.svg | 4 ++ docs/notes/01_c-basic/07_xdx/assets/5.svg | 4 ++ docs/notes/01_c-basic/07_xdx/assets/6.svg | 4 ++ docs/notes/01_c-basic/07_xdx/assets/7.svg | 4 ++ docs/notes/01_c-basic/07_xdx/assets/8.svg | 4 ++ docs/notes/01_c-basic/07_xdx/assets/9.svg | 4 ++ docs/notes/01_c-basic/07_xdx/index.md | 58 +++++++++++++++++++++- 7 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 docs/notes/01_c-basic/07_xdx/assets/10.svg create mode 100644 docs/notes/01_c-basic/07_xdx/assets/5.svg create mode 100644 docs/notes/01_c-basic/07_xdx/assets/6.svg create mode 100644 docs/notes/01_c-basic/07_xdx/assets/7.svg create mode 100644 docs/notes/01_c-basic/07_xdx/assets/8.svg create mode 100644 docs/notes/01_c-basic/07_xdx/assets/9.svg diff --git a/docs/notes/01_c-basic/07_xdx/assets/10.svg b/docs/notes/01_c-basic/07_xdx/assets/10.svg new file mode 100644 index 0000000..1956dbb --- /dev/null +++ b/docs/notes/01_c-basic/07_xdx/assets/10.svg @@ -0,0 +1,4 @@ + + + +
传输数据 1
stdin(输入设备,键盘等)
内存
传输数据 2
stdin(输入设备,键盘等)
内存
传输数据 3
stdin(输入设备,键盘等)
内存
传输数据 4
stdin(输入设备,键盘等)
内存
传输数据 5
stdin(输入设备,键盘等)
批量处理
内存
CPU
输入缓冲区
\ No newline at end of file diff --git a/docs/notes/01_c-basic/07_xdx/assets/5.svg b/docs/notes/01_c-basic/07_xdx/assets/5.svg new file mode 100644 index 0000000..1f26451 --- /dev/null +++ b/docs/notes/01_c-basic/07_xdx/assets/5.svg @@ -0,0 +1,4 @@ + + + +
CPU
内存
IO 设备
\ No newline at end of file diff --git a/docs/notes/01_c-basic/07_xdx/assets/6.svg b/docs/notes/01_c-basic/07_xdx/assets/6.svg new file mode 100644 index 0000000..6bde1be --- /dev/null +++ b/docs/notes/01_c-basic/07_xdx/assets/6.svg @@ -0,0 +1,4 @@ + + + +
CPU 核心
内存
IO 设备
1 级缓存
2 级缓存
3 级缓存
\ No newline at end of file diff --git a/docs/notes/01_c-basic/07_xdx/assets/7.svg b/docs/notes/01_c-basic/07_xdx/assets/7.svg new file mode 100644 index 0000000..ea6d443 --- /dev/null +++ b/docs/notes/01_c-basic/07_xdx/assets/7.svg @@ -0,0 +1,4 @@ + + + +
内存
stdout(输出设备,屏幕等)
stdin(输入设备,键盘等)
数据
CPU
\ No newline at end of file diff --git a/docs/notes/01_c-basic/07_xdx/assets/8.svg b/docs/notes/01_c-basic/07_xdx/assets/8.svg new file mode 100644 index 0000000..3373e8c --- /dev/null +++ b/docs/notes/01_c-basic/07_xdx/assets/8.svg @@ -0,0 +1,4 @@ + + + +
内存
stdout(输出设备,屏幕等)
stdin(输入设备,键盘等)
数据
CPU
输入缓冲区
输出缓冲区
\ No newline at end of file diff --git a/docs/notes/01_c-basic/07_xdx/assets/9.svg b/docs/notes/01_c-basic/07_xdx/assets/9.svg new file mode 100644 index 0000000..22a80de --- /dev/null +++ b/docs/notes/01_c-basic/07_xdx/assets/9.svg @@ -0,0 +1,4 @@ + + + +
传输数据 1
stdin(输入设备,键盘等)
接收并处理数据 1
内存
等待处理数据 2
CPU
传输数据 2
stdin(输入设备,键盘等)
接收并处理数据 2
内存
等待处理数据 3
CPU
传输数据 3
stdin(输入设备,键盘等)
接收并处理数据 3
内存
等待处理数据 4
CPU
传输数据 4
stdin(输入设备,键盘等)
接收并处理数据 4
内存
等待处理数据 5
CPU
传输数据 5
stdin(输入设备,键盘等)
接收并处理数据 5
内存
CPU
\ No newline at end of file diff --git a/docs/notes/01_c-basic/07_xdx/index.md b/docs/notes/01_c-basic/07_xdx/index.md index 0d300eb..a7449f1 100644 --- a/docs/notes/01_c-basic/07_xdx/index.md +++ b/docs/notes/01_c-basic/07_xdx/index.md @@ -86,4 +86,60 @@ > - ① 存储器越往上速度越快,但是价格越来越贵, 越往下速度越慢,但是价格越来越便宜。 > - ② 正是由于计算机各个部件的速度不同,容量不同,价格不同,导致了计算机系统/编程中的各种问题以及相应的解决方案。 -* 正是由于 CPU、内存以及 IO 设备之间的速度差异,从而导致了计算机的性能瓶颈,即所谓的 \ No newline at end of file +* 正是由于 CPU、内存以及 IO 设备之间的速度差异,从而导致了计算机的性能瓶颈,即所谓的`“冯·诺依曼体系结构的瓶颈”`。 + +![](./assets/5.svg) + +* 因为 CPU 的处理速度远远快于内存和 IO 设备,导致在等待数据处理和传输的时候,CPU 大部分处于空闲状态。就是这种显著的速度差异就导致了计算机的性能瓶颈,限制了整个计算机系统的效率。 + +> [!NOTE] +> +> * 对于硬件的这种显著的速度差异,我们程序员是无法解决的。 +> * 但是,为了平衡三者之间的速度鸿沟,我们可以通过引入`缓冲区`技术,来降低系统的 IO 次数,降低系统的开销。 + +* 其实,在硬件上也是有`缓冲区`的,即:CPU 内部集成了缓存,将经常使用到的数据从内存中加载到缓存中。 + +> [!NOTE] +> +> 对于缓存和内存中数据的同步解决方案,会有各种各样的算法,如:LRU 等。 + +![](./assets/6.svg) + +## 1.3 缓冲区 + +### 1.3.1 概述 + +* 我们所编写的程序,都是运行在内存中的,如果我们不使用缓冲区,那么其在内存中就是这样的,如下所示: + +![](./assets/7.svg) + +* 而缓冲区的本质就是在`内存`中开辟一块用来`临时存储数据`的`区域`,它在速度较慢的内存和 IO 设备起到了桥梁的作用,那么其在内存中就是这样的,如下所示: + +![](./assets/8.svg) + +> [!NOTE] +> +> 其实,C 语言中的 `printf` 函数和 `scanf` 函数,其内部就使用了缓冲区。 +> +> * ① 当我们使用 `printf` 函数输出数据的时候,数据并不会立即就写出到输出设备(如:屏幕等)。而是先将其放置到 `stdout 缓冲区`中,然后在满足条件的时候,再从缓冲区中刷新到输出设备。 +> * ② 当我们使用 `scanf` 函数输入数据的时候,数据并不会立即就从输入设备中读取(如:键盘等)。而是先将其放置到 `stdin 缓冲区`中,然后在满足条件的时候,再从缓冲区中加载数据。 + +### 1.3.2 缓冲区到底如何实现系统效率的提升? + +* 如果没有缓冲区,假设有 5 个数据,输入设备每次传递 1 个数据,CPU 必须立即接收并处理,因此有 5 次 IO 操作,每次都是逐个处理,如下所示: + +![](./assets/9.svg) + +* 如果存在没有缓冲区,假设有 5 个数据,输入设备每次传递 1 个数据,但它们先存储到缓冲区中。CPU 在缓冲区满时一次性处理多个数据,减少了频繁的等待,如下所示: + +![](./assets/10.svg) + +> [!IMPORTANT] +> +> 假设每次 IO 操作的时间是 1 秒,CPU 处理数据的时间也是 1 秒,那么: +> +> * ① 没有缓冲区的情况下,总耗时是:5 次 I/O 操作 + 5 次处理 = 10 秒,即:没有缓冲区的情况下,每次 I/O 操作和处理器的处理是交替进行的,因此总共需要 10 秒(5 次 I/O + 5 次处理) +> * ② 使用缓冲区的情况下,总耗时是:5 次 I/O 操作 + 1 次批量处理 = 6 秒,即:使用缓冲区的情况下,I/O 操作和处理器处理是分开的,I/O 操作先全部完成,处理器一次性批量处理所有数据。因此,总耗时减少为 6 秒(5 秒传输 + 1 秒处理)。 +> +> 使用缓冲区能够显著减少总的执行时间,因为它允许处理器批量处理数据,而不是在每次数据传递后都进行等待处理。 +