FIO 磁盘性能测试

2023-11-12

FIO 磁盘性能测试

fio 是一个开源压力测试工具,主要用来测试硬盘 io 性能。这个工具的可定制性非常强,可以根据测试者的想法进行各种混合 io 测试,它支持 13 种不同类型 io 引擎(libaio、sync、mmap、posixaio、network 等等)。它可以测试块设备或文件,可以通过多线程或进程模拟各种 io 操作,可以测试统计 iops、带宽和时延等性能。我们主要使用 fio 工具进行存储性能测试。

磁盘性能基础知识

虽然现在大范围的使用 SSD,但是在一些存储系统中 HDD 还是大批量被使用,毕竟便宜;SSD 固态硬盘通过电存储,HDD 机械硬盘通过机械运动存储,很明显 SSD 在存储性能上有先天优势;影响 SSD 性能的主要因素有存储主控芯片的设计、闪存单元设计,当然还有工艺水平。目前 SSD 主控芯片设计最前沿的技术在 Intel 手上,Intel SSD 性能是目前最好的。
针对 HDD 机械硬盘的性能,数据的读写有 95% 的耗时是消耗在机械运动上,一次数据操作为一次 IO 服务,它包括以下几个环节:

  1. 寻道时间,是指将读写磁头移动至正确的磁道上所需要的时间。寻道时间越短,I/O 操作越快,目前磁盘的平均寻道时间一般在 3-15ms;
  2. 旋转延迟,是指盘片旋转将请求数据所在扇区移至读写磁头下方所需要的时间。旋转延迟取决于磁盘转速,通常使用磁盘旋转一周所需时间的 1/2 表示。比如,7200rpm 的磁盘平均旋转延迟大约为 60*1000/7200/2 = 4.17ms
  3. 内部接口传送时间,即从磁盘盘片到内部磁盘缓冲传送的时间,量级是 440 微秒。
  4. 外部接口传输时间,即从磁盘缓冲到接口传送的时间,量级是 110 微秒。

对于一个确定的磁盘,旋转延迟保持不变,而内部接口传送时间和外部接口传输时间微秒级别,基本可以忽略不计,那么影响 HDD 性能核心就是寻道时间;

对磁盘性能的度量有两个指标:IOPS,IO 吞吐/带宽;

  1. IOPS 指的是每秒可以完成的 IO 服务的次数,一次 IO 服务主要的耗时是寻道时间上,如果是大量的随机 IO,那么每次寻道时间都处于上限值,IOPS 下降;

    • 理论上下限 = [1000ms/(3ms+4.17ms),1000ms/(15ms+4ms)] = [139,53];但是真实环境下,一个磁盘 IOPS 的值受每次 IO 读写的数据大小,比如 512B,4k,1M 等各个值下 IOPS 肯定是有区别的;
  2. IO 吞吐表示在指定时间内,完成的 IO 读写数据字节数,它的值和每次 IO 读写的数据大小有密切关系,也从而会影响 IOPS,比如每次读写数据块较大,从而最大化的降低了寻道带来的开销,从而提高吞吐,但是此时 IOPS 就会减小;

实例说明:写入 10000 个大小为 1kb 的文件到硬盘上,耗费的时间要比写入 10 个 1mb 大小的文件多得多。

  1. 虽然数据总量都是 10mb,但是 10000 个 1kb 大小的文件在磁道上数据分布不连续,可能需要上千个 IOPS 才能完成数据的全部读取,大大增加了寻道时间,耗时长。
    • 种情况用来指导 HDD IOPS 性能测试,即小数据块多请求次数测试。
  2. 相比较而言,10 个 1mb 大小的文件在磁道上数据分布连续性更好,可能只需要十几个 IOPS 就能完成数据的全部读取,大大降低了寻道时间,耗时少。
    • 这种情况用来指导 HDD IO 吞吐/带宽性能测试,即大数据块少请求次数测试。

对磁盘性能 IOPS 和 IO 吞吐的追求与业务有密切关系,比如大文件存储希望吞吐可以做到最高,而小文件或随机读写的业务更加追求 IOPS;如果业务对吞吐和 IOPS 都有一定依赖,那么就需要找到一个合适的 blocksize 来设置每次 IO 大小,从而在 IOPS 和吞吐之间均衡,即(IOPS × block_size = IO 吞吐);

提供 IO 性能的方法:

  1. IO 合并,即将多个 IO 请求进行合并;
  2. IO 拆封,采用 raid 等磁盘阵列,将一个普通 IO 请求,并发的分发到多个物理磁盘,提供 IO 吞吐
  3. IO 大 cache,每次 IO 写操作都不直接写到物理设备,而是存储在 IO cache 中,直到 cache 满了再更新到磁盘设备中;
  4. IO 预读 Buffer,通过 IO 预判读,虽然一次只读 4k,但是预判 512k 到 buffer,当然这个对 4k 以下的应用来说是一个坑。

NOTE:在计算机程序设计当中,往往从时间局部性、空间局部性及缓存命中率几个角度对程序进行性能优化,而且在计算机领域,这种局部性原理都是通用的。

fio 安装

Ubuntu 环境

sudo apt-get install fio gunplot 

嵌入式平台或源码编译
fio 源码下载地址:https://github.com/axboe/fio/tags

git clone https://github.com/axboe/fio.git
 ./configure --cc=arm-linux-gnueabihf-gcc --prefix=./build
 make                                          
 make install 

确认系统安装是否有 libaio 和 libaio-devel,如果没有安装这两个包,fio 工具不能使用异步的 libaio 引擎。如果在安装 fio 前未安装 libaio 和 libaio-devel,那么安装了 libaio 和 libaio-devel 后需要重新编译安装 fio,不然也无法使用异步引擎 libaio。

使用指导

fio 是可以根据测试要求配置不同参数进行 io 性能测试的工具,可配置的参数有上百个,几乎可以覆盖所有的 io 模型,详细参数可查询 fio 的官网获取:https://fio.readthedocs.io/en/latest/fio_doc.html
存储性能测试中常用的参数如下所示:

参数 参数值 解释
filename 设备名或文件名如:裸设备 /dev/sdb,文件 /home/test.img 定义测试对象,一般是设备或者文件。如果想测试裸盘设备 /dev/sdb,可以设置 filename=/dev/sdb;如果想要测试文件系统性能,则可以设置 filename=/home/test.img
name 测试名称 定义测试名称。必填项,本地 fio 测试的名称,对性能没有影响。
rw 测试类型,可选值有:read,write,rw,randread,randwrite,randrw 定义测试的读写类型:read-顺序读,write-顺序写,rw(readwrite)- 混合顺序读写,randread- 随机读,randwrite-随机写,randrw-混合随机读写。对于读写混合类型来说,默认读写比例为 1:1
rwmixwrite rwmixread 混合读写中读写占用比例,可选值为[0,100] 定义在混合读写模式中,写或读所占的比例。举例来说,rwmixread 值为 10,则表示读写比为 10:90。
ioengine io 引擎选择,可选值有 sync、libaio、psync、vsync、mmap 等等 定义 fio 如何下发 io 请求。sync:基本的 read、write io。 libaio:linux 原生的异步 io,linux 只支持 non-buffer 情况下的排队操作。默认值为 psync,该模式为同步 io 模型,异步 io 模型 libaio,一般结合 direct=1 使用。
direct 0 或 1 定义是否使用 direct io:值为 0,表示使用 buffered io;值为 1,表示使用 direct io。
bs 带单位数字 定义 io 的块大小,单位是 k,K,m,M。默认值为 4k。
numjobs 正整数 定义测试的进程/线程数,默认值为 1,如果指定了 thread 参数,则使用单进程多线程模式,否则使用多进程模式。
iodepth 正整数 定义每个进程/线程可以同时下发的 io 任务数,默认为 1,适用于异步 io 场景,同步 io 场景要等前一个 io 任务完成才能下发下一个任务,所以 iodepth 并不起作用。

其他相关参数:

参数 参数值 解释
size 整数 定义 io 操作的数据量,除非指定了 runtime 这个参数,fio 会将指定大小的数据量全部读写完成,才会停止测试。 该参数的值,可以是带单位的数字,比如 size=2G,表示读/写的数据量为 2G;也可以是百分比,比如 size=20%,表示读写的数据量占该设备/文件的 20% 的空间;除了表示 io 操作数据量,size 还表示 io 操作的范围,与 offset 配合一起读写[offset,offset+size]范围内的数据
runtime 正整数 定义测试时间,以秒为单位。对于指定的文件设备,如果在测试时间内完成了读写操作,则会保持相同的负载循环进行读写。
ramp_time 正整数 定义测试的热身时间,以秒为单位。热身时间不计入测试统计。
thinktime 正整数 设置当一个 io 完成后,等待多少时间再下发另一个 io,单位为微妙。一般用于模拟应用等待、处理事务等。
time_based NA 默认值为 0,如果设置了该参数,则本次测试会一直运行到 runtime 结束为止。
offset 定义测试起始位置 fio 在硬盘测试的起始位置,配合顺序读写使用。不同的 offset 对 HDD 的性能影响大,对 SSD 理论无影响。
group_reporting NA 对于测试并发数大于 1 的情况,如果想要将所有进程/线程的测试结果进行统计,输出总的测试结果,而不是各自单独输出,可以使用此参数。
cpus_allowed 指定 cpu 的 core fio 测试的所有进程/线程可以选择的 cpu 核,可以是单独一个或者多个核,也可以是一个范围。
output 结果输出路径 结果输出文件,默认直接把结果打印到命令行,设置后会把结果写进目标文件,命令行则不显示结果。
命令行测试方法
# fio -name=mytest \
-filename=/dev/sdb \
-direct=1 \
-iodepth=20 \
-thread \
-rw=randread \
-ioengine=libaio \
-bs=16k \
-size=5G \
-numjobs=2 \
-runtime=300 \
-group_reporting \
  • name=mytest:本次测试的名称 mytest,自已定义。
  • filename=/dev/sdb:测试裸盘的名称,通常选择需要测试的盘的 data 目录,是没有文件系统的裸盘。
  • direct=1:测试过程绕过机器自带的 buffer。使测试结果更真实。
  • iodepth=20:每个线程每次下发 20 个 io 任务。
  • rw=randread:测试随机读的 I/O。
  • ioengine=libaio:io 引擎使用 libaio 模式。
  • bs=16k:单次 io 的块文件大小为 16k。
  • size=5G:本次的测试文件大小为 5G,以每次 16k 的 io 进行测试。
  • numjobs=2:本次的测试线程为 2。
  • runtime=300:测试时间为 300 秒,如果不写则一直将 5G 文件分 16k 每次写完为止。
  • group_reporting:关于显示结果的,汇总每个进程的信息。

顺序读:

fio -name=mytest -filename=/dev/sdb -direct=1 -iodepth=20 -thread -rw=read -ioengine=libaio -bs=16k -size=5G -numjobs=2 -runtime=300 -group_reporting

顺序写:

fio -name=mytest -filename=/dev/sdb -direct=1 -iodepth=20 -thread -rw=write -ioengine=libaio -bs=16k -size=5G -numjobs=2 -runtime=300 -group_reporting

随机写:

fio -name=mytest -filename=/dev/sdb -direct=1 -iodepth=20 -thread -rw=randwrite -ioengine=libaio -bs=1k -size=5G -numjobs=2 -runtime=300 -group_reporting

混合顺序读写:

fio -name=mytest -filename=/dev/sdb -direct=1 -iodepth=20 -thread -rw=rw -ioengine=libaio -bs=16k -size=5G -numjobs=2 -runtime=300 -group_reporting

混合随机读写:

fio -name=mytest -filename=/dev/sdb -direct=1 -iodepth=20 -thread -rw=randrw -ioengine=libaio -bs=16k -size=5G -numjobs=2 -runtime=300 -group_reporting

测试文件系统

fio -name=mytest -filename=/test/test.img -direct=1 -iodepth=20 -thread -rw=randread -ioengine=libaio -bs=16k -size=5G -numjobs=2 -runtime=300 -group_reporting
  • filename=/test/test.img:测试文件的名称,为已经做过文件系统的空间。这种方式通常是将一块裸盘,进行分区、格式化,然后挂载到此目录。
配置文件方式

fio 也可以通过执行 job 方式,同时执行多个不同的文件,使用很少的命令执行测试。测试命令:fio job。

job 文件的编写参考:

[global]
ioengine=libaio
direct=1
size=8g
filesize=500g
time_based
rw=randrw
rwmixread=70
bs=4k
runtime=120

[job1]
filename=/dev/sdb
numjobs=16
iodepth=1

[job2]
filename=/dev/sdc
numjobs=16
iodepth=1
  • job 文件里的每一个 job 都是同时执行的,global 部分是全局的。
  • 如果想要分开各自执行并统计结果,就要计算一下时间使用 startdelay 参数控制。
  • 使用命令行同时测试多个设备,压力会分布不均。但是通过 job 文件方式配置可以解决,这就相当于开两个窗口同时执行多条命令了。
  • 在 job 配置文件中,增加 group_reporting 参数,在测试完成后就可以看到统计的性能数据了。
测试结果分析
# fio -name=hdd7k -filename=/dev/sdb -direct=1 -iodepth=20 -thread -rw=rw -ioengine=libaio -bs=4k -size=10G -numjobs=10 -runtime=300 -group_reporting
hdd7k: (g=0): rw=rw, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=20
...
fio-3.29-7-g01686
Starting 10 threads
Jobs: 10 (f=9): [f(10)][100.0%][r=10.9MiB/s,w=10.7MiB/s][r=2785,w=2742 IOPS][eta 00m:00s] 
hdd7k: (groupid=0, jobs=10): err= 0: pid=73595: Thu Jan 13 11:19:06 2022
  read: IOPS=3258, BW=12.7MiB/s (13.3MB/s)(3820MiB/300065msec)
    slat (usec): min=2, max=547, avg= 6.47, stdev= 4.04
    clat (usec): min=27, max=4722.3k, avg=33300.91, stdev=77842.79
     lat (usec): min=47, max=4722.3k, avg=33307.62, stdev=77842.14
    clat percentiles (usec):
     |  1.00th=[    725],  5.00th=[   1745], 10.00th=[   2737],
     | 20.00th=[   3228], 30.00th=[   3687], 40.00th=[   4621],
     | 50.00th=[   5866], 60.00th=[   7832], 70.00th=[  14615],
     | 80.00th=[  39060], 90.00th=[ 116917], 95.00th=[ 135267],
     | 99.00th=[ 333448], 99.50th=[ 463471], 99.90th=[ 843056],
     | 99.95th=[1052771], 99.99th=[1686111]
   bw (  KiB/s): min=  200, max=91945, per=100.00%, avg=13408.99, stdev=1441.98, samples=5840
   iops        : min=   50, max=22985, avg=3351.87, stdev=360.48, samples=5840
  write: IOPS=3261, BW=12.7MiB/s (13.4MB/s)(3823MiB/300065msec); 0 zone resets
    slat (usec): min=3, max=532, avg= 6.68, stdev= 4.17
    clat (usec): min=38, max=4725.1k, avg=28027.57, stdev=69203.56
     lat (usec): min=50, max=4725.2k, avg=28034.48, stdev=69202.94
    clat percentiles (usec):
     |  1.00th=[    848],  5.00th=[   1860], 10.00th=[   2802],
     | 20.00th=[   3294], 30.00th=[   3752], 40.00th=[   4621],
     | 50.00th=[   5800], 60.00th=[   7439], 70.00th=[  11994],
     | 80.00th=[  27919], 90.00th=[ 111674], 95.00th=[ 122160],
     | 99.00th=[ 265290], 99.50th=[ 392168], 99.90th=[ 784335],
     | 99.95th=[ 977273], 99.99th=[1904215]
   bw (  KiB/s): min=  208, max=91939, per=100.00%, avg=13475.63, stdev=1444.81, samples=5818
   iops        : min=   52, max=22984, avg=3368.52, stdev=361.18, samples=5818
  lat (usec)   : 50=0.01%, 100=0.01%, 250=0.06%, 500=0.32%, 750=0.53%
  lat (usec)   : 1000=0.74%
  lat (msec)   : 2=4.20%, 4=28.23%, 10=32.04%, 20=8.83%, 50=8.44%
  lat (msec)   : 100=4.75%, 250=10.40%, 500=1.10%, 750=0.23%, 1000=0.07%
  lat (msec)   : 2000=0.05%, >=2000=0.01%
  cpu          : usr=0.18%, sys=0.45%, ctx=964464, majf=0, minf=210
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=100.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.1%, 64=0.0%, >=64=0.0%
     issued rwts: total=977794,978699,0,0 short=0,0,0,0 dropped=0,0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=20

Run status group 0 (all jobs):
   READ: bw=12.7MiB/s (13.3MB/s), 12.7MiB/s-12.7MiB/s (13.3MB/s-13.3MB/s), io=3820MiB (4005MB), run=300065-300065msec
  WRITE: bw=12.7MiB/s (13.4MB/s), 12.7MiB/s-12.7MiB/s (13.4MB/s-13.4MB/s), io=3823MiB (4009MB), run=300065-300065msec

Disk stats (read/write):
  sdb: ios=480787/482996, merge=492621/492299, ticks=6820973/5217066, in_queue=7483700, util=100.00%

Fio 正在运行时,会显示任务的状态信息,如下:

# 运行中
Jobs: 10 (f=10): [M(10)][2.7%][r=2508KiB/s,w=2856KiB/s][r=627,w=714 IOPS][eta 04m:52s]

# 已完成
Jobs: 10 (f=9): [f(10)][100.0%][r=10.9MiB/s,w=10.7MiB/s][r=2785,w=2742 IOPS][eta 00m:00s]
  • 第一组方括号内的字符表示每个线程的当前状态。 第一个字符是任务文件中定义的第一个任务,以此类推。 可能的值(按典型的生命周期顺序)是:
P      Thread setup, but not started.
C      Thread created.
I      Thread initialized, waiting or generating necessary data.
p      Thread running pre-reading file(s).
/      Thread is in ramp period.
R      Running, doing sequential reads.
r      Running, doing random reads.
W      Running, doing sequential writes.
w      Running, doing random writes.
M      Running, doing mixed sequential reads/writes.
m      Running, doing mixed random reads/writes.
D      Running, doing sequential trims.
d      Running, doing random trims.
F      Running, currently waiting for fsync(2).
V      Running, doing verification of written data.
f      Thread finishing.
E      Thread exited, not reaped by main thread yet.
-      Thread reaped.
X      Thread reaped, exited with an error.
K      Thread reaped, exited due to signal.
  • 运行中这一行的意思是:执行 10 个任务,打开文件描述符 10 个,正在运行混合顺序读写共 10 个任务,已完成 2.7%,读 2508KiB/s,写 2856KiB/s;读 IOPS 627,写 IOPS 714,评估需要 04m:52s 完成所有任务。
  • Fio 完成或 ctrl+c 取消都会输出所有结果信息,下面一一解释关键参数:
hdd7k: (groupid=0, jobs=10): err= 0: pid=73595: Thu Jan 13 11:19:06 2022
  • 定义的任务名称,groupid,聚合的任务数,最后一个错误 id(0 表示没有错误)和 pid,完成时间。

  • read/write/trim:IOPS 表示每秒平均 IOPS;BW 表示平均带宽,BW 后面的数据是 2 进制带宽,括号中是 10 进制带宽;最后两个值表示(二进制总 IO 大小/总运行时间)

  • slat:提交任务延迟(submission latency),也就是异步 IO 指令生成消耗的时间(min 最小时间,max 最大时间,avg 平均时间,stdev 标准差)。对于同步 I/O,这一行不会显示,因为 slat 实际上是完成延迟(completion latency)。这个值的单位可以是纳秒、微秒或毫秒,由 fio 自动选择合适的单位。在 --minimal 模式下,延迟总是以微秒计算。

  • clat:完成延迟(completion latency),这表示从提交 IO 指令到内核再到 IO 指令全部运行所需要的时间,不包括提交任务延迟(submission latency);同步 IO 情况下 clat 通常等于(或非常接近)0,因为从提交到完成仅仅表示 CPU 时间(IO 指令已经生成了)。

  • lat:总延迟(total latency),这表示从 fio 创建 IO 单元到 IO 指令全部运行所花费的时间。

  • clat percentiles:完成延迟百分比分布,注意,从源码来看,它不是 slat + clat;它有自己的结构体描述。理解思路参考下面的 lat(nsec/usec/msec)。

  • bw:基于样本的带宽统计数据。最好是在同一磁盘同一组线程中取样,才具有实际意义,因为磁盘竞争访问才符合实际情况。

  • iops:基于样本的 IOPS 统计数据。同 bw。

  • lat(nsec/usec/msec):IO 完成延迟(I/O completion latencies)的分布情况,这表示从 IO 离开 fio 到它完成的时间。与上面单独的 read/write/trim 部分不同,这里和其余部分中的数据适用于报告组的所有 IO。50=0.01% 意味着在 50us 以下完成了 0.01% 的 IO,100=0.01% 意味着 0.01% 的 IO 需要 50 到 99us 才能完成。依次类推。

  • cpu:CPU 使用率。 用户和系统时间,以及该线程所经历的上下文切换次数、系统和用户时间的使用情况,最后是主要和次要页面错误的数量。 CPU 利用率数字是报告组中任务的平均值,而上下文和故障计数器是求和的。

  • IO depths:任务生命周期内 IO 深度的分布。 这些数字被分成 2 的幂,每个条目涵盖了从该值到低于下一个条目的深度,例如,16= 涵盖了从 16 到 31 的深度。请注意,深度分布条目所覆盖的范围可能与等效的 submit/complete 分布条目所覆盖的范围不同。

  • IO submit:在一个提交调用中提交了多少个 IO 块。 每个条目表示这个数量,直到前一个条目。例如,4=100% 意味着我们每次提交调用提交的 IO 在 1 到 4 之间。 请注意,提交分布条目所覆盖的范围可以不同于等效深度分布条目所覆盖的范围。

  • IO complete:同理 submit,表示完成的 IO 块。

  • IO issued rwt:发布的 read/write/trim 请求数量以及缺少和丢掉的数量。

  • IO latency:这些值用于 latency_target 和相关选项。 当使用这些选项时,该片段描述满足指定时延目标所需的 IO 深度。

以上是报告中的详细参数说明,下面对总结报告数据说明一下:

Run status group 0 (all jobs):
 READ: bw=12.7MiB/s (13.3MB/s), 12.7MiB/s-12.7MiB/s (13.3MB/s-13.3MB/s), io=3820MiB (4005MB), run=300065-300065msec
WRITE: bw=12.7MiB/s (13.4MB/s), 12.7MiB/s-12.7MiB/s (13.4MB/s-13.4MB/s), io=3823MiB (4009MB), run=300065-300065msec

Disk stats (read/write):
sdb: ios=480787/482996, merge=492621/492299, ticks=6820973/5217066, in_queue=7483700, util=100.00%
  • bw:该组中所有线程的最小和最大带宽紧随该组中所有线程的总带宽。 括号外的值是 2 进制的格式,括号内的值是10 进制格式的等价值。
  • io:整合该组中所有线程执行的 IO。 格式与 bw 相同。
  • run:该组中线程的最小和最长运行时间。
  • ios:所有线程组的 IO 数。
  • merge:IO 调度器执行的合并次数。
  • ticks:保持磁盘忙碌的 ticks 数。
  • in_queue:在磁盘队列中总耗时。
  • util:磁盘利用率。 值为 100% 表示我们一直保持磁盘繁忙,50% 表示磁盘有一半时间处于空闲状态。

注意事项

测试注意事项
  1. fio 测试会对系统的硬盘进行读写,会存在破坏客户数据的风险,因此在生产环境上要谨慎使用,不建议对生产环境的硬盘进行裸盘读写测试。
  2. 如果需要进行测试,最好创建一个文件,然后对指定的文件进行读写。
  3. 如果需要做性能分析或调优,测试过程中需要收集 iostat 信息,例如:iostat -xd 1 1000 > result.log。
性能调优注意事项
  1. FIO 进行性能对比测试的时候,一定要保持参数一致,否则参数差异会导致结果差异。
  2. 在测试文件系统时,要先写一个大文件,然后再做硬盘 IO 读写测试。避免小数据块 IO 模型下读取不到文件而读到其他地方去。
  3. 如果是 SSD,测试过程中最好进行绑核设置,因为 IOPS 太大,如果线程运行在 CPU0 或者是有其他应用占用的核,那么可能会达不到最佳性能。绑核使用 taskset -c 31 ./fio… 命令实现。对应使用哪个核,可以执行 numactl -H 查询核的信息。

参考:
FIO 磁盘性能测试

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FIO 磁盘性能测试 的相关文章

  • 命名互斥体的 Mono 替代方案

    在 Windows NET 上 命名的互斥体可用于同步多个进程 不幸的是 Mono 在 Linux 上不太支持这一点 他们的发行说明 http www mono project com Release Notes Mono 2 8 Shar
  • BeagleBone Black 如何用作大容量存储设备?

    是否可以使用 BB 作为大容量存储设备 我希望将其连接到可以从 USB 连接 例如 USB 闪存驱动器 读取文件的音频播放器并充当包含一个特定文件夹的数据存储设备 及其子文件夹 从文件系统 如果可能 在连接到开发板的闪存驱动器上 正如设备规
  • GCC 详细模式输出解释

    我是 Linux 新手 谁能向我解释一下我的 hello world 程序的以下详细模式输出 另外 这些文件是做什么用的crt1 o crti o crtend o crtbegin o and crtn o and lc and lgcc
  • Linux 中的 Windows NAmed Pipes 替代品

    我们正在将现有的 Windows 代码移植到 Linux 我们使用 ACE 作为抽象层 我们使用 Windows 命名管道与多个客户端进行通信并执行重叠操作 linux 下这个相当于什么 我检查了linux命名管道 FIFO 但它们似乎只支
  • 使用 Python 将阿拉伯语或任何从右到左书写系统的字符串打印到 Linux 终端

    非常简单的例子是 city print city 我期望输出是 但实际上输出是相反的字符串 字母看起来有点不同 因为它们有开始 中间和结束形式 我无法将其粘贴到此处 因为复制粘贴会再次更正字符串的顺序 如何在 Linux 终端上正确打印阿拉
  • 在 Linux 服务器上创建和编辑 MS-Word 文档?

    希望开发处理文档的服务器端应用程序 源文档大多是MS Word 2003 2007 即MS版本的Docx 希望服务器应用程序能够在linux或windows上运行 想知道在linux下读写MS Word文件最好的工具或库是什么 兼容性是最重
  • 如何使用 PyAudio 选择特定的输入设备

    通过 PyAudio 录制音频时 如何指定要使用的确切输入设备 我的电脑有两个麦克风 一个内置 一个通过 USB 我想使用 USB 麦克风进行录音 这流类 https people csail mit edu hubert pyaudio
  • 删除 Python 中某些操作的 root 权限

    在我的 Python 脚本中 我执行了一些需要 root 权限的操作 我还创建并写入文件 我不想由 root 独占所有 而是由运行我的脚本的用户独占所有 通常 我使用以下命令运行脚本sudo 有办法做到上述吗 您可以使用以下方式在 uid
  • sudo pip install python-Levenshtein 失败,错误代码 1

    我正在尝试在 Linux 上安装 python Levenshtein 库 但每当我尝试通过以下方式安装它时 sudo pip install python Levenshtein 我收到此错误 命令 usr bin python c 导入
  • 设置 Vim 背景颜色

    当我尝试更改背景颜色时 vimrc或者直接在 Vim 中使用以下命令 set background dark 这根本不影响我的背景 也没有light选项 不过 当我运行 gvim 时 看起来还不错 有没有办法在不更改 Konsole 设置的
  • PHP 日志文件颜色

    我正在编写一个 PHP 日志文件类 但我想为写入文件的行添加颜色 我遇到的问题是颜色也会改变终端的颜色 我想要实现的是仅更改写入日志文件的行的颜色 class logClass extends Singleton private funct
  • C# - OPC-UA 服务器应用程序尚未在 Linux 计算机中创建 PKI 证书

    当我跑步时OPC UA serverWindows 机器中的 C 应用程序 然后 OPC UA 服务器已创建证书路径C ProgramData OPC Foundation pki own 并在此路径中生成一些证书 但是当我在中安装 OPC
  • bash "&" 不打印 "[1]+ Done "

    我在 bashrc 中调用一个脚本来打印打开终端时收到的新消息数 我希望该调用在访问网络时是非阻塞的 有时需要几秒钟 这意味着我无法使用终端直到完成 但是如果我输入 mailcheck 在我的 bashrc 中 它工作正常 但然后打印一个空
  • Linux mremap 不释放旧映射?

    我需要一种方法将页面从一个虚拟地址范围复制到另一个虚拟地址范围 而无需实际复制数据 范围很大 延迟很重要 mremap 可以做到这一点 但问题是它也会删除旧的映射 由于我需要在多线程环境中执行此操作 因此我需要旧映射能够同时使用 因此稍后当
  • VSCODE 在 Linux 上不适用于我

    刚刚了解 VSCODE 很高兴尝试一下 我下载 解压并运行可执行文件 我得到 Code 2183 0429 201254 ERROR browser main loop cc 170 Running without the SUID san
  • 如何获取 bash 中从 Ping 接收到的数据包的百分比?

    当 ping 主机时 我希望输出仅显示收到的数据包 已发送 5 个 的百分比 我想我需要使用grep不知怎的 但我不知道如何 我是 bash 编程的新手 这是我所在的地方 ping c 5 q host grep grep 中应该包含什么
  • 如何防止 CMake 在构建时(而不是安装时)为共享库创建符号链接?

    我正在使用 CMake 在 Linux 上使用 Bullet3 构建一个项目 在构建整个解决方案时 它会构建附加了 SOVERSION 的 Bullet 输出库 并创建一个不带版本的符号链接 对于我的特定场景 我不喜欢这种行为 并且我不想编
  • 如何更改 Kubernetes 中的文件系统观察程序限制 (fs.inotify.max_user_watches)

    我在用着pm2 https github com Unitech pm2查看保存我的应用程序服务器的 NodeJS 程序源代码的目录 该程序在 Kubernetes 集群中运行 但是 我收到此错误 ENOSPC System limit f
  • shell中基于正则表达式的颜色突出显示输出

    我想知道是否可以用颜色突出显示与某些字符串匹配的 shell 命令的输出 例如 如果我运行 myCommand 输出如下 gt myCommand DEBUG foo bar INFO bla bla ERROR yak yak 我希望所有
  • 如何从python导入路径中删除当前目录

    我想使用 Mercurial 存储库hg本身 也就是说 我克隆了 Mercurialhttps www mercurial scm org repo hg https www mercurial scm org repo hg并想运行一些h

随机推荐

  • 【javascript】全选按钮

    当点击全选按钮时 与之相关的所有选项都会被自动框选 效果 代码
  • 43黑马QT笔记之Qt下Tcp/Udp通信过程

    43黑马QT笔记之Qt下Tcp Udp通信过程 前提 Qt下的网络通信需要加上 QT newwork 模块 1 Qt下Tcp的通信过程 1 共有三个套接字 客户端有一个QTcpServer监听套接字 服务端有两个 分别是QTcpServer
  • vlookup匹配 匹配结果错误_明明有数据,为什么我的VLOOKUP总是匹配不出来?

    经常用vlookup函数匹配数据的小伙伴们经常会遇到表格中明明有数据 却总是匹配不到的情况 下面盘点下那些年匹配时遇到的坑 单元格中存在空白 下图中A B两列分别存放着员工姓名和员工得分数据 现在要求提取员工H及员工D的得分情况 大家都知道
  • 太方便了,钉钉上就可完成代码发布审批啦!

    如今 不少企业的发布流程要求代码发布到生产环境前需要经过审批 这种发布审批流程 对企业的的CI CD工具提出了新要求 CI CD步骤里需要支持人工卡点审批 并在人工卡点审批通过后能自动触发后续的部署工作 云效流水线Flow发布审批示例 如上
  • 10道海量数据处理

    1 海量日志数据 提取出某日访问百度次数最多的那个IP 此题 在我之前的一篇文章算法里头有所提到 当时给出的方案是 IP的数目还是有限的 最多2 32个 所以可以考虑使用hash将ip直接存入内存 然后进行统计 再详细介绍下此方案 首先是这
  • pycharm中pip升级失败问题

    pycharm中pip升级失败问题 在使用部分第三方库时会使用更高版本的pip 例如TensorFlow需要18 x版本的pip 但是pycharm中进行pip升级时会出现各种问题 甚至显示升级成功 其实并没有 笔者阅读了一些博客上的文章发
  • 十大最佳虚拟化软件

    正如该术语在计算术语中暗示的那样 虚拟化涉及到创建虚拟操作系统 网络平台和存储设备 当今世界 需要复杂的计算机系统来帮助管理大型企业 虚拟化帮助计算机系统和网络管理员使用相同的硬件运行并行操作系统进程 这意味着硬件和软件集成的有效使用 它还
  • centos 查看内核 版本

    查看系统内核版本 方法一 root multiview cat proc version Linux version 3 10 0 693 el7 x86 64 builder kbuilder dev centos org gcc ver
  • Linux下C语言使用openssl库进行MD5校验

    作者 无脑仔的小明 出处 http www cnblogs com wunaozai 我们以一个字符串为例 新建一个文件filename txt 在文件内写入hello 然后在Linux下可以使用命令md5sum filename txt计
  • 2.3mnist手写数字识别之网络结构精讲(百度架构师手把手带你零基础实践深度学习原版笔记系列)

    2 3mnist手写数字识别之网络结构精讲 百度架构师手把手带你零基础实践深度学习原版笔记系列 目录 2 3mnist手写数字识别之网络结构精讲 百度架构师手把手带你零基础实践深度学习原版笔记系列 概述 经典的全连接神经网络 卷积神经网络
  • [SQL]SQL server 常用代码

    判断数据库是否存在 USE eshop 选取数据库 GO IF EXISTS SELECT FROM sysdatabases WHERE name eshop 判断eshop是否存在 DROP DATABASE eshop 删除 GO 新
  • Cisco路由器 VOIP 配置

    Cisco路由器VOIP 配置解析 在企业网络中推广IP语音技术有很多优点 例如可以控制数据流量 保证语音质量 充分利用企业租用的数据线路资源 节省传统的长途话费等等 企业使用IP语音技术 可以将语音 数据和多媒体通信融合在一个集成的网络中
  • 玩转Mixly – 2、Arduino AVR编程 之 输入输出

    以下内容源自Mixly官方技术文档 https mixly readthedocs io zh CN latest Arduino AVR 01Input Output html 输入 输出 输入 输出所包含的指令主要分为四部分 控制管脚的
  • CSS 轻松搞定标签(元素)居中问题

    在CSS里 标签位置居中一直是困扰Web前端的难题 在本文中 我对这类问题进行了探究和给出了几点建议 供读者参考 1 行内标签 1 1 水平居中 在父级标签中使用 text align center 效果 1 2 垂直居中 如果是单行 则为
  • 工业级路由器和家用路由器的区别_5G工业级路由器有哪些优势

    一 5G工业级路由器比4G工业级路由器强在哪 对于消费者而言 5G的价值在于它拥有比4G LTE更快的速度 峰值速率可达几十Gbps 例如你可以在一秒钟内下载一部高清电影 而4G LTE可能要10分钟 5G网关 5G路由 因而 和4G工业级
  • Mysql中行转列和列转行

    一 行转列 即将原本同一列下多行的不同内容作为多个字段 输出对应内容 建表语句 DROP TABLE IF EXISTS tb score CREATE TABLE tb score id INT 11 NOT NULL auto incr
  • C语言的关键字,字符和ASCII码

    关键字的介绍 C语言的关键字有 1 数据类型关键字 2 控制语句关键字 3 存储类型关键字 4 其他关键字 数据类型关键字有12个 char 声明字符型变量或函数 double 声明双精度变量或函数 enum 声明枚举类型 float 声明
  • 10-11

    函数 函数体内部的语句在执行时 一旦执行到return时 函数就执行完毕 并将结果返回 因此 函数内部通过条件判断和循环可以实现非常复杂的逻辑 如果没有return语句 函数执行完毕后也会返回结果 只是结果为undefined 定义方法一
  • ROS笔记 URDF及rviz可视化及遇到的问题

    在学习http gazebosim org tutorials tut ros urdf中遇到一些问题 因为版本不同出现错误 GazeboRosControlPlugin missing while using DefaultRobotHW
  • FIO 磁盘性能测试

    FIO 磁盘性能测试 fio 是一个开源压力测试工具 主要用来测试硬盘 io 性能 这个工具的可定制性非常强 可以根据测试者的想法进行各种混合 io 测试 它支持 13 种不同类型 io 引擎 libaio sync mmap posixa