Linux 为什么CPU访问硬盘的速度巨慢

2023-10-20 23:20

本文主要是介绍Linux 为什么CPU访问硬盘的速度巨慢,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

http://www.differencebetween.net/technology/difference-between-von-neumann-and-harvard-architecture/

机械硬盘(Hard Disk Drive、HDD)和固态硬盘(Solid State Drive、SSD)是两种最常见的硬盘,作为计算机的外部存储,CPU 想要访问它们存储的数据需要很长时间,如下表所示,在 SSD 中随机访问 4KB 数据所需要的时间是访问主存的 1,500 倍,机械磁盘的寻道时间是访问主存的 100,000 倍:

WorkLatency
L1 cache reference0.5 ns
Branch mispredict5   ns
L2 cache reference7   ns
Mutex lock/unlock25   ns
Main memory reference100   ns
Compress 1K bytes with Zippy3,000   ns
Send 1K bytes over 1 Gbps network10,000   ns
Read 4K randomly from SSD*150,000   ns
Read 1 MB sequentially from memory250,000   ns
Round trip within same datacenter500,000   ns
Read 1 MB sequentially from SSD*1,000,000   ns
Disk seek10,000,000   ns
Read 1 MB sequentially from disk20,000,000   ns
Send packet CA->Netherlands->CA150,000,000   ns

 

表 1 - 2012 年延迟数字对比


虽然磁盘的寻道时间只需要 10ms,但是在 CPU 看来已经是非常长的时间了,当我们将上述的时间等比例放大后,就能直观地感受到它们的性能差异。如果 CPU 访问 L1 缓存需要 1 秒,那么访问主存需要 3 分钟、从 SSD 中随机读取数据需要 3.4 天、磁盘寻道需要 2 个月,网络传输可能需要 1 年多的时间。

在计算机体系结构中,硬盘属于一种常见的输入输出设备,操作系统在启动时不一定需要硬盘,它既可以通过硬盘启动,也可以通过网络设备或者外部设备启动,所以硬盘不是计算机运行的必要条件。

Difference between Von Neumann and Harvard Architecture

                                                                             von-neumann-architecture.svg

作为一种外部的输入输出设备,与 CPU 缓存和内存相比,硬盘极慢的读取和写入速度就显得比较合理了,然而几千倍甚至几十万倍的速度差异也确实让人很难想象或者接受,在这篇文章中,我们会分析为什么 CPU 访问硬盘的速度非常慢:

  • CPU 访问硬盘数据的过程比较复杂,它会先通过 I/O 操作将磁盘中的数据读入内存,再访问内存的数据

  • 机械硬盘在访问磁盘中的数据依赖的是机械结构,需要移动磁盘中的机械臂

 

I/O 操作


CPU 想要访问磁盘中的数据一定要先通过 I/O 操作将磁盘中的数据读入到内存中,再访问存储在内存中的数据。计算机中包含三种比较常见的 I/O 操作 — 编程 I/O(Programmed I/O)、中断驱动 I/O(Interrupt-driven I/O)和直接内存访问(Direct Memory Access),我们接下来将依次介绍上述的这几种操作:

                                                                                                                                                                                                        io-operation

                                                                                                                                                                                                    图 2 - 常见 I/O 操作

执行 I/O 操作最简单的形式就是使用编程 I/O,使用编程 I/O 时,CPU 会负责全部的工作,如果我们想要在屏幕上输出 Hello World,CPU 每次都会向 I/O 设备中写入一个新字符,写入后会轮询设备的状态等待它完成工作后写入新的字符。这种方式虽然简单,但是它会占用全部的 CPU 资源,在某些复杂的系统中会造成计算资源的严重浪费。

中断驱动 I/O 是执行 I/O 操作的一种更高效方式,在编程 I/O 中,CPU 会主动获取设备的状态并等待设备闲置,但是如果使用了中断驱动 I/O,设备会在闲置时主动发起中断暂停当前进程并保存上下文,而操作系统会执行 I/O 设备的中断处理程序:

  • 如果当前不包含待打印的字符,停止中断处理程序并恢复暂停的进程;

  • 如果当前包含待打印的字符,将下一个字符拷贝到设备中并恢复暂停的进程;

使用中断驱动 I/O 可以在设备繁忙时,让 CPU 能够处理其它任务,尽可能地提高 CPU 的利用率,不再浪费珍贵的计算资源。与编程 I/O 相比,中断驱动 I/O 将一部分工作交给了 I/O 设备,所以能够提高资源的利用率。

直接内存访问会利用 DMA 控制器来执行 I/O 操作,中断驱动 I/O 需要为每个字符触发操作系统中断,这会消耗一定的 CPU 时间。当我们使用 DMA 控制器时,CPU 会一次将缓冲区中的数据全部读到 DMA 控制器中,DMA 控制器会负责将数据按字符写入 I/O 设备:

                                                                                                                                                                                                              dma-controller

                                                                                                                                                                                                               图 3 - DMA I/O

虽然 DMA 控制器可以解放 CPU 并减少中断次数,但是它的执行速度与 CPU 相比却很慢,如果 DMA 控制器不能快速驱动 I/O 设备,CPU 可能就会等待 DMA 控制器触发中断,在这种情况下,中断驱动 I/O 或者编程 I/O 可以提供更快的访问速度。

在默认情况下,我们都会使用 DMA 控制器来执行 I/O 任务,不过编程 I/O 和中断驱动 I/O 也不是不能接受的选项。当 CPU 经常需要等待 DMA 控制器执行 I/O 任务时,使用中断驱动 I/O 甚至轮询的编程 I/O 都可以得到更高的吞吐量,然而无论使用哪种方式,I/O 都是程序中比较耗时的复杂操作。

 

机械硬盘


机械硬盘(Hard Disk Drive、HDD)是一种基于电子的、非易失的机械数据存储设备,它使用磁性存储器存储并查找磁盘上的数据,在读取和写入数据的过程中,硬盘机械臂连接的磁头会读写磁盘表面的位[^8]。

正是因为磁盘具有比较复杂的机械结构,所以磁盘的读取和写入都要花费很多时间,数据库的读写性能也基本都依赖于磁盘的性能,如果我们在使用机械硬盘的数据库中随机查询一条数据,这可能会触发磁盘的随机 I/O,然而将数据从磁盘读取到内存中所需要的成本是非常大的,普通磁盘(非 SSD)加载数据需要经过队列、寻道、旋转以及传输的这些过程,大概要花费 10ms 左右的时间。

                                                                                                                                                                                                        disk-random-io

                                                                                                                                                                                                     图 4 - 磁盘的随机 I/O

我们在估算数据库的查询时可以使用 10ms 这个数量级对随机 I/O 占用的时间进行估算,这里想要说的是随机 I/O 对于数据库的查询性能影响会非常大,而顺序读取磁盘中的数据时速度可以达到 40MB/s,这两者的性能差距有几个数量级,因此我们也应该尽量减少随机 I/O 的次数,这样才能提高性能。

固态硬盘(Solid State Drive、SSD)是一种以闪存作为持久存储器的电脑存储设备[^9]。与机械硬盘不同,固态硬盘中不包含任何的机械结构,我们使用它读取或者存储数据时不会使用到任何的机械结构,因为一切过程都是由电路完成的,所以 SSD 的读写速度比 HDD 快很多。

                                                                                                                                                                                                            hdd-ssd-price

                                                                                                                                                                                                    图 5 - HDD 和 SSD 的价格

机械硬盘和 SSD 从诞生后价格都在不断降低,机械硬盘是今天数据中心使用的主要外部存储,大多数通用的商用服务器都会使用机械硬盘作为主要的外部存储,但是因为 SSD 的读写速度是机械硬盘的几十倍,所以越来越多的服务器,尤其是数据库都会使用 SSD 作为外部存储。不过作为具有机械结构的外部存储设备,它虽然结构非常成熟并且具有较大的容量,但是它在受到震动时很容易受到外界的干扰。

 

总结


硬盘是计算机上的外部存储设备,它可以持久存储大量数据,然而 CPU 无法直接访问硬盘中的数据,当计算机启动时操作系统会将硬盘中的数据加载到内存中以便 CPU 访问,但是如果 CPU 要访问的数据不在内存中,那么我们需要花费几千倍甚至几十万倍的时间来读取数据,这主要是由以下两个原因造成的:

  • CPU 需要通过 I/O 操作访问外部存储中的数据,编程 I/O、中断驱动 I/O 和 DMA 几种方式都会带来额外开销并占用较多的 CPU 时间;

  • 机械硬盘会通过机械结构访问其中存储的数据,每一次硬盘的随机 I/O 都需要执行队列、寻道、旋转和转移数据几个过程,大约需要消耗 10ms 的时间;

正如我们在文章中提到的,硬盘不是计算机运行的必要硬件设备,计算机可以从磁盘、光盘等任意外部存储设备中将启动所需要的数据加载到内存中并正常启动,不过硬盘已经是今天最为常见的外部存储设备了。到最后,我们还是来看一些比较开放的相关问题,有兴趣的读者可以仔细思考一下下面的问题:

  • 写入到硬盘上的数据一定会被持久存储,不会丢失吗?

  • 内存中的数据为什么在断电重启之后就会被清空?

这篇关于Linux 为什么CPU访问硬盘的速度巨慢的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/250349

相关文章

Linux磁盘分区、格式化和挂载方式

《Linux磁盘分区、格式化和挂载方式》本文详细介绍了Linux系统中磁盘分区、格式化和挂载的基本操作步骤和命令,包括MBR和GPT分区表的区别、fdisk和gdisk命令的使用、常见的文件系统格式以... 目录一、磁盘分区表分类二、fdisk命令创建分区1、交互式的命令2、分区主分区3、创建扩展分区,然后

Linux中chmod权限设置方式

《Linux中chmod权限设置方式》本文介绍了Linux系统中文件和目录权限的设置方法,包括chmod、chown和chgrp命令的使用,以及权限模式和符号模式的详细说明,通过这些命令,用户可以灵活... 目录设置基本权限命令:chmod1、权限介绍2、chmod命令常见用法和示例3、文件权限详解4、ch

Linux内核之内核裁剪详解

《Linux内核之内核裁剪详解》Linux内核裁剪是通过移除不必要的功能和模块,调整配置参数来优化内核,以满足特定需求,裁剪的方法包括使用配置选项、模块化设计和优化配置参数,图形裁剪工具如makeme... 目录简介一、 裁剪的原因二、裁剪的方法三、图形裁剪工具四、操作说明五、make menuconfig

关于Java内存访问重排序的研究

《关于Java内存访问重排序的研究》文章主要介绍了重排序现象及其在多线程编程中的影响,包括内存可见性问题和Java内存模型中对重排序的规则... 目录什么是重排序重排序图解重排序实验as-if-serial语义内存访问重排序与内存可见性内存访问重排序与Java内存模型重排序示意表内存屏障内存屏障示意表Int

Linux使用nohup命令在后台运行脚本

《Linux使用nohup命令在后台运行脚本》在Linux或类Unix系统中,后台运行脚本是一项非常实用的技能,尤其适用于需要长时间运行的任务或服务,本文我们来看看如何使用nohup命令在后台... 目录nohup 命令简介基本用法输出重定向& 符号的作用后台进程的特点注意事项实际应用场景长时间运行的任务服

SpringBoot实现基于URL和IP的访问频率限制

《SpringBoot实现基于URL和IP的访问频率限制》在现代Web应用中,接口被恶意刷新或暴力请求是一种常见的攻击手段,为了保护系统资源,需要对接口的访问频率进行限制,下面我们就来看看如何使用... 目录1. 引言2. 项目依赖3. 配置 Redis4. 创建拦截器5. 注册拦截器6. 创建控制器8.

什么是cron? Linux系统下Cron定时任务使用指南

《什么是cron?Linux系统下Cron定时任务使用指南》在日常的Linux系统管理和维护中,定时执行任务是非常常见的需求,你可能需要每天执行备份任务、清理系统日志或运行特定的脚本,而不想每天... 在管理 linux 服务器的过程中,总有一些任务需要我们定期或重复执行。就比如备份任务,通常会选在服务器资

SpringBoot如何访问jsp页面

《SpringBoot如何访问jsp页面》本文介绍了如何在SpringBoot项目中进行Web开发,包括创建项目、配置文件、添加依赖、控制层修改、测试效果以及在IDEA中进行配置的详细步骤... 目录SpringBoot如何访问JSP页python面简介实现步骤1. 首先创建的项目一定要是web项目2. 在

Linux限制ip访问的解决方案

《Linux限制ip访问的解决方案》为了修复安全扫描中发现的漏洞,我们需要对某些服务设置访问限制,具体来说,就是要确保只有指定的内部IP地址能够访问这些服务,所以本文给大家介绍了Linux限制ip访问... 目录背景:解决方案:使用Firewalld防火墙规则验证方法深度了解防火墙逻辑应用场景与扩展背景:

Linux下MySQL8.0.26安装教程

《Linux下MySQL8.0.26安装教程》文章详细介绍了如何在Linux系统上安装和配置MySQL,包括下载、解压、安装依赖、启动服务、获取默认密码、设置密码、支持远程登录以及创建表,感兴趣的朋友... 目录1.找到官网下载位置1.访问mysql存档2.下载社区版3.百度网盘中2.linux安装配置1.