Kernel wmb/mb宏的作用

本文探讨了内存屏障如何防止编译器优化和CPU乱序执行导致的问题,并介绍了Linux下的barrier()宏及mb()系列宏的具体应用。
内存屏障主要解决的问题是编译器的优化和CPU的乱序执行。
编译器在优化的时候,生成的汇编指令可能和c语言程序的执行顺序不一样,在需要程序严格按照c语言顺序执行时,需要显式的告诉编译不需要优化,这在linux下是通过barrier()宏完成的,它依靠volidate关键字和memory关键字,前者告诉编译barrier()周围的指令不要被优化,后者作用是告诉编译器汇编代码会使内存里面的值更改,编译器应使用内存里的新值而非寄存器里保存的老值。
同样,CPU执行会通过乱序以提高性能。汇编里的指令不一定是按照我们看到的顺序执行的。linux中通过mb()系列宏来保证执行的顺序。具体做法是通过mfence/lfence指令(它们是奔4后引进的,早期x86没有)以及x86指令中带有串行特性的指令(这样的指令很多,例如linux中实现时用到的lock指令,I/O指令,操作控制寄存器、系统寄存器、调试寄存器的指令、iret指令等等)。简单的说,如果在程序某处插入了mb()/rmb()/wmb()宏,则宏之前的程序保证比宏之后的程序先执行,从而实现串行化。wmb的实现和barrier()类似,是因为在x86平台上,写内存的操作不会被乱序执行。
实际上在RSIC平台上,这些串行工作都有专门的指令由程序员显式的完成,比如在需要的地方调用串行指令,而不像x86上有这么多隐性的带有串行特性指令(例如lock指令)。所以在risc平台下工作的朋友通常对串行化操作理解的容易些。
<think>我们讨论的是如何通过 `iostat -xmdz 3 /dev/sdb` 命令的输出结果来判断硬盘是否处于格式化进程中以及是否在工作。格式化进程通常涉及大量的连续写入操作,而一般的工作负载可能具有不同的特征。 从用户提供的引用[1]中,我们看到一个示例输出,其中显示了高写入吞吐量(wMB/s 约为 1000 MB/s),并且写入请求合并(wrqm/s)较高。同时,await(平均I/O等待时间)较低,%util(设备利用率)接近100%。这些是磁盘被高负载使用的典型迹象。 格式化操作通常是对整个磁盘进行写入(比如用零填充),因此会表现出以下特征: 1. 持续的高写入吞吐量(wMB/s 接近磁盘的物理写入极限) 2. 高设备利用率(%util 持续接近100%) 3. 几乎没有读取操作(r/s 和 rMB/s 接近0) 4. 平均请求大小(avgrq-sz)较大,因为格式化通常使用大块连续写入(例如,我们之前用 `dd` 命令时设置 `bs=4M`,所以请求大小在4MB左右) 5. 写入请求合并(wrqm/s)可能会较高,因为内核可能会尝试合并相邻的写入请求,但如果是大块连续写入,合并可能不会太多(因为每个请求已经很大) 在 `iostat` 的输出中,我们关注以下字段: - `w/s`: 每秒写入次数 - `wMB/s`: 每秒写入的数据量(兆字节) - `avgrq-sz`: 平均请求大小(单位:扇区,通常一个扇区为512字节,所以要转换成字节需要乘以512,转换成兆字节需要除以2048) 例如,avgrq-sz为2927.08(扇区) -> 2927.08 * 512 / 1048576 ≈ 1.43 MB (注意:实际上1MB=1048576字节,但通常我们用1024进制,即1MB=1048576字节,所以除以1048576/1024=1024?实际上,我们通常用1MB=1024KB=1048576字节。但是,在iostat中,wMB/s已经是兆字节,所以avgrq-sz(扇区)转换为兆字节:avgrq-sz * 512 / 1048576) 不过,我们也可以直接看wMB/s和w/s,然后计算每个请求的平均大小(MB)= wMB/s / w/s,然后乘以1024得到KB(或者乘以1048576得到字节)?其实,avgrq-sz的单位是扇区,所以乘以512就是字节数,再除以1048576就是MB。所以每个请求的平均MB数 = (avgrq-sz * 512) / 1048576。 - `await`: 平均I/O等待时间(包括队列等待和服务时间,单位毫秒) - `%util`: 设备利用率(百分比) 格式化进程的特征: 1. `wMB/s` 持续接近磁盘的最大写入速度(例如,SATA III硬盘最大约600MB/s,但实际可能低一些,比如150-200MB/s?但用户引用中的速度达到了1000MB/s以上,这可能是一个高性能设备或者RAID?但用户是4T SATA硬盘,一般不会超过600MB/s。所以需要结合具体磁盘型号)。 2. `%util` 持续接近100%。 3. `avgrq-sz` 较大,比如在格式化时使用大块(如4M)写入,那么平均请求大小应该在4MB左右,换算成扇区数:4MB = 4 * 1048576 字节 = 4194304 字节,除以512得到扇区数:4194304/512=8192扇区。所以如果看到avgrq-sz在8000扇区左右(即大约4MB),那么很可能是大块连续写入。 4. 写入请求的等待时间(w_await)应该较低,因为连续写入是磁盘最快的操作方式(没有寻道时间开销)。 但是,用户之前格式化使用的是 `dd` 命令,并且设置了 `bs=4M`,所以每个写请求是4MB。那么对应的avgrq-sz应该是 4MB对应的扇区数:4*1024*1024/512 = 8192扇区(因为4MB=4194304字节,4194304/512=8192扇区)。 所以,判断依据: - 如果 `wMB/s` 持续很高(接近磁盘的最大写入速度)且 `%util` 接近100%,同时 `avgrq-sz` 在8000扇区左右(或者根据你设置的块大小计算),那么硬盘很可能正在进行格式化(用零填充)。 - 如果 `wMB/s` 很低,而 `%util` 也很低,那么硬盘可能没有在工作。 - 如果 `wMB/s` 不是特别高,但 `%util` 很高,那么可能是随机写入,而不是格式化(因为格式化是连续写入)。 另外,注意格式化可能分为两个阶段:先写零(或者模式填充),然后创建文件系统。`mkfs` 命令在创建文件系统时可能不会持续写入整个磁盘,所以速度可能不会一直保持最高。但是,如果使用 `dd` 写零,那么会持续整个磁盘。 因此,总结如下: 使用命令: `iostat -xmdz 3 /dev/sdb` 输出解读: - 每隔3秒输出一组数据 - 观察以下指标: 1. wMB/s: 持续高写入速度(比如超过100MB/s,具体取决于磁盘) 2. %util: 持续接近100% 3. avgrq-sz: 如果接近8192扇区(4MB)则可能是大块连续写入(格式化填充) 4. w/s: 每秒写入次数,因为块大所以这个值不会特别高(例如,写4MB块,要达到200MB/s的写入速度,则w/s=200/4=50左右) 例如: wMB/s = 100,avgrq-sz=8000扇区(即4MB),那么w/s应该是 100/4 = 25 左右。 所以,如果观察到这样的特征,可以判断硬盘正在被大块数据连续写入(可能是格式化填充)。 另外,格式化过程中通常没有读取操作(r/s, rMB/s 为0或很低)。 如果硬盘在工作但不是格式化,可能表现为: - 有读取操作 - 写入速度不稳定,时高时低 - avgrq-sz 较小(比如随机读写,请求大小可能为4KB,对应8个扇区) - 或者虽然写入速度高,但avgrq-sz与格式化时不同 注意:不同的磁盘其最大写入速度不同,需要结合实际磁盘性能来看。 引用[1]中的输出示例: wMB/s: 1088.20, 1097.41, 1065.24, 1079.73, 1068.08 (非常高,超过了普通SATA盘的极限,可能是高性能设备或RAID) avgrq-sz: 2927.08, 2926.44, 2730.43, 2980.17, 2741.14 (扇区) 转换成MB: (2927.08 * 512) / 1048576 ≈ 1.43 MB (所以每个请求大约是1.43MB,而不是4MB) w/s: 761.39, 768, 799, 742, 798 (大约750-800次写入/秒) 计算请求大小:wMB/s除以w/s,例如1088.20/761.39≈1.43MB,与上面计算一致。 所以,这个输出显示的是每次写入请求大约1.43MB,而不是4MB。因此,这可能是另一种工作负载,不一定是我们之前设置的4MB块大小的格式化。但如果是格式化,可能块大小设置不同(比如1M?)。 因此,判断是否格式化,需要结合实际情况(比如你格式化命令使用的块大小)以及磁盘的实际表现。 结论: 通过 `iostat` 输出,我们可以判断硬盘正在进行高负载的连续写入(可能是格式化),但具体是否格式化还要结合操作历史(是否执行了格式化命令)以及写入请求的大小是否与格式化命令设置的块大小匹配。 相关问题: 1. 如何根据 `iostat` 输出判断磁盘的瓶颈类型? 2. 磁盘格式化过程中,`iostat` 的输出特征有哪些? 3. 除了 `iostat`,还有哪些命令可以监控磁盘格式化进度? 4. 为什么格式化磁盘时 `iostat` 显示的写入速度有时低于磁盘标称速度? 5. 如何通过 `iostat` 输出计算磁盘的实际平均写入块大小? </think>### 通过 `iostat -xmdz 3 /dev/sdb` 判断硬盘状态 根据您提供的引用[1]和格式化操作的特征,以下是判断硬盘是否处于格式化进程及是否工作的关键指标分析: #### 🔍 格式化进程的判断依据(连续写入特征) 1. **高持续写入吞吐量** - `wMB/s` 持续高位(如 >100 MB/s,具体值取决于磁盘性能) - 示例:引用[1]中 `wMB/s` 稳定在 1065~1097 MB/s *格式化时通常接近磁盘物理写入极限* 2. **大块连续写入** - `avgrq-sz`(平均请求大小)显著增大 - 格式化时通常 > 2000 扇区(≈1 MB) - 示例:引用[1]中 `avgrq-sz` = 2730~2980 扇区(1.33~1.45 MB)[^1] 3. **高设备利用率** - `%util` 持续 >90% (表示磁盘持续繁忙) - 示例:引用[1]中 `%util` = 19~21% (疑似部分虚拟化环境) 4. **低等待队列** - `avgqu-sz`(平均队列长度)接近 0 - 示例:引用[1]中 `avgqu-sz` = 0.20~0.22 [^1] *连续写入时I/O请求直接处理无需排队* #### ⚙️ 硬盘工作状态的综合判断 | **指标** | 格式化中 | 正常工作 | 空闲状态 | |----------------|-----------------------|----------------------|------------------| | `wMB/s` | 持续高位(>100MB/s) | 波动明显 | ≈0 | | `%util` | >90% | 间歇性峰值 | <5% | | `avgrq-sz` | >2000扇区 | 大小混合(512~4096) | - | | `w_await` | 较低且稳定(<1ms) | 波动较大 | - | | 写入模式 | 连续大块 | 随机/混合 | - | #### 📊 实际案例分析(基于引用[1]) ```bash Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await ... %util sampleblk1 0.00 558.42 0.00 761.39 0.00 1088.20 2927.08 0.22 ... 20.79 ``` 1. **格式化特征**: - 持续高写入 `wMB/s=1088` - 大块请求 `avgrq-sz=2927扇区≈1.43MB` - 零读取操作 `r/s=0` 2. **异常点**: - `%util=20.79%` 偏低 → 可能虚拟化环境或RAID卡缓冲[^1] - `await=0.29ms` 极低 → 表明无物理寻道时间 #### ✅ 操作建议 1. **格式化确认命令**: ```bash # 结合进程查看 pgrep -af "dd|mkfs|pv" && iostat -xmdz 3 /dev/sdb ``` 2. **关键监控指令**: ```bash watch -n 3 "iostat -xmd /dev/sdb | awk 'NR==3||NR==4'" ``` --- ### 📚 相关问题 1. 如何区分磁盘格式化与大数据拷贝的 `iostat` 表现? 2. 为什么 `avgrq-sz` 值能反映写入模式特征? 3. `%util` 在 SSD 和 HDD 上有何不同解读? 4. 如何计算 `avgrq-sz` 的实际字节大小? (公式:$ \text{实际字节} = \text{avgrq-sz} \times 512 $) 5. 当 `%util > 100%` 时可能是什么原因? > **诊断提示**:格式化操作通常伴随持续高`wMB/s` + 大`avgrq-sz` + 高`%util`三特征,但虚拟化/RAID环境可能使`%util`失真[^1]。建议结合`pgrep`确认进程。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值