??xml version="1.0" encoding="utf-8" standalone="yes"?> Linux IOpȝ的架构图 一Q?/span>讑֤-------- 影响盘性能的因?/span> 盘的{速媄(jing)响硬盘的整体性能。一般情况下转速越大,性能?x)越好?/span> 盘的性能因素主要包括两个Q?.q_讉K旉2传输速率?/span> q_讉K旉包括两方面因素:(x) q_寻道旉(Average Seek Time)是指盘的磁头移动到盘面指定道所需的时?/span>。一般在3ms?5ms之间?/span> q_旋{{待旉(Latency)是指头已处于要讉K的磁道,{待所要访问的扇区旋{至磁头下方的旉?/span>一般在2ms?ms之间?/span> 传输速率(Data Transfer Rate) 盘的数据传输率是指盘d数据的速度Q单位ؓ(f)兆字节每U(MB/sQ。磁盘每U能传输80M~320M字节?/span> 传输速率包括内部传输速率和外部传输速率?/span> 内部传输?Internal Transfer Rate) 也称为持l传输率(Sustained Transfer Rate)Q它反映?jin)硬?/span>~冲?/span>未用时的性能。内部传输率主要依赖于硬盘的旋{速度?/span> 外部传输率(External Transfer RateQ也UCؓ(f)H发数据传输?/span>Q?span>Burst Data Transfer RateQ或接口传输率,它标U的?/span>pȝȝ与硬盘缓冲区之间的数据传输率Q外部数据传输率?/span>盘接口cd?/span>盘~存的大有兟뀂STAT2 的传输速率?00MB/sU别?/span> 因此在硬件上,提高盘性能的关键主要是降低q_讉K旉?/span> 二.讑֤驱动 内存到硬盘的传输方式QpollQ中断,DMA DMAQ当 CPU 初始化这个传输动作,传输动作本n是由 DMA 控制?nbsp;来实行和完成?/span> DMA控制器获得ȝ控制权后QCPU卛_挂v或只执行内部操作Q由DMA控制器输?gu)写命令,直接控制RAM与I/O接口q行DMA传输。DMA每次传送的是磁盘(sh)盔R的扇区。Scatter-gather DMA允许传送不盔R的扇区?/span> CPU性能与硬盘(sh)内存的数据传输速率关系不大?/span> 讑֤驱动内有一个结构管理着IO的请求队?/span> structrequest_queueQinclude/linux/Blkdev.hQ?/span> q里不仅仅有dh的数据块Q还有用于IO调度的回调函数结构。每ơ需要传输的时候,׃队列中选出一个数据块交给DMAq行传输?/span> 所?a name="_GoBack">IO调度的回调函数这是降低^均访问的旉的关键?/span> 三.OS IO调度?/span> Linux kernel提供?jin)四个调度器供用户选择。他们是noop,cfq,deadline,as。可以在pȝ启动时设|内核参数elevator=<name>来指定默认的调度器。也可以在运行时为某个块讑֤讄IO调度E序?/span> 下面来简要介l这四个调度器的甉|调度法?/span> NoopQ最单的调度法。新的请求L被添加到队头或者队,然后L从队头中选出要被处理的h?/span> CFQQ(Complete FarinessQueueingQ它的目标是在所有请求的q程中^均分配IO的带宽。因此,它会(x)Ҏ(gu)q程创徏自己的请求队列,然后IOh攑օ相应的队列中。在使用轮{法从每个非空的队列中取出IOh?/span> DeadlineQ用了(jin)四个队列Q两个以盘块序h序的d队列Q两个以最后期限时间排序的d队列。算法首先确定下一个读写的方向Q读的优先高(sh)写。然后检查被选方向的最后期限队列:(x)如果最后期限时间的队列中有时的请求,则将刚才的请求移动至队尾Q然后在盘h序队列中从超时请求开始处理。当处理完一个方向的h后,在处理另一个方向的h。(读请求的时旉?00msQ写h的超时时间是5sQ?/span> AnticipatoryQ它是最复杂的IO调度法。和deadline法一h四个队列。还附带?jin)一些启发式{略。它?x)从当前的磁头位|后的磁盘号中选择h。在调度?jin)一个由P(pn)q程的IOh后,?x)检查下一个请求,如果q是Pq程的请求,则立卌度,如果不是Q同旉Pq程很快?x)发(gu)求,则还廉大?ms的时间等待Pq程的IOh?/span> Write/Read函数 以ext3的writeZQ?/span> pȝ调用write()的作用就是修攚w高速缓存内的一些页的内容,如果高速缓存内没有所要的则分配q追加这些页?/span> 当脏达C定数量或者超时后Q将脏页刷回盘。也可以执行相关pȝ调用?/span> Z么要辑ֈ一定数量,是因为gq写能在一定层度上提高pȝ的性能Q这也得块讑֤的^均读h?x)多于写h?/span> 在程序中调用write函数Q将q入pȝ调用f_op->write。这个函数将调用ext3的do_sync_write。这个函数将参数装后调用generic_file_aio_write。由参数名可以看出同步写变成?jin)异步写。如果没有标记O_DIRECTQ将调用函数generic_file_buffered_write写的内容写qkernel的高速页~存?sh)。Buffer是以page为单位即4k。之后当调用cond_resched()q行q程的调度,DMA?x)将buffer中的内容写进盘?/span> 所以当每次?k为单位写入硬盘时效率?x)达到最高。下面是UNIX环境高~程的实验结果:(x) 下图是linux 的块讑֤的数据操作层ơ:(x) Sector扇区Q是讑֤驱动和IO调度E序处理数据_度?/span> Block块:(x)是VFS和文件系l处理数据的_度。其大小不唯一Q可以是512,1024,2048,4096字节。内核操作的块大是4096字节?/span> SegmentD:(x)是DMA传送的单位。每一个段包含?jin)相(c)扇区Q它能DMA传送不盔R的扇区?/span> 四.用户E序 Ҏ(gu)以上的分析,我们?span>write buffer一般设|ؓ(f)4K的倍数?/span> 在程序中有意识的延迟写。这个是os的策略,当然也可以应用到E序的设计中。当然也?x)有~点Q?.如果g错误或掉?sh),则?x)丢失内容Q做额外的备份)(j)2.需要额外的内存I间。(牺牲内存来提高I(y)O的效率)(j) 我们q需Ҏ(gu)pȝ的IO调度器的调度{略Q设计出不同的IO{略。尽量降低磁盘的q_讉K旉Q降低请求队列,提高数据传输的速率?/span> 五.监控盘的工具和指标 Iostat–x –k 1 -x昄更多的消?nbsp;-k数据以KB为单?1每秒昄一?/span> 输出昄的信?/span> IowaitQcpu{待未完成的IOh而空闲的旉的比例?/span> IdleQcpuI闲且无I(yng)Oh的比例?/span> rrqm/sQ每U这个设备相关的dh有多被Merge?jin)?/span> wrqm/sQ每U这个设备相关的写入h有多被Merge?jin)?/span> rsec/sQ每U读取的扇区敎ͼ wsec/Q每U写入的扇区数?/span> r/sQ每U完成的?I/O 讑֤ơ数。即 delta(rio)/s w/sQ每U完成的?I/O 讑֤ơ数。即 delta(wio)/s awaitQ每一个IOh的处理的q_旉Q单位是毫秒Q。包括加入请求队列和服务的时间?/span> svctm: q_每次讑֤I/O操作的服务时间?/span> avgrq-sz: q_每次讑֤I/O操作的数据大?(扇区)。即 delta(rsect+wsect)/delta(rio+wio) %utilQ在l计旉内所有处理IO旉Q除以dl计旉。例如,如果l计间隔1U,该设备有0.8U在处理IOQ?.2U闲|,那么该设备的%util = 0.8/1 = 80%Q所以该参数暗示?jin)设备的J忙E度。一般地Q如果该参数?00%表示讑֤已经接近满负药行了(jin)Q当然如果是多磁盘,即%util?00%Q因为磁盘的q发能力Q所以磁盘(sh)用未必就C(jin)瓉Q?/span> 下面我们做一个实验来分析一?/span> 我们使用命o(h) time dd if=/dev/zero of=/home/zhouyuan/mytest bs=1M count=3000 向mytest写入数据Q写?G?/span> 截取部分的状态监控:(x) 如图2Q当两条数据 iowait 辑ֈ?/span> 99% 以上Q写入的数据?Q这是因为DMA内存的中的数据传输l设备。结合图1的前两条数据Q利用率辑ֈ?9%+却没有写入的盘块?/span> 如图3Qiowait下降Q说明cpu开始执行相关程序,而此时块讑֤开始写入的数据。这两个操作是异步进行的?/span> Vmstat–k –n 1 Swap si: 从磁盘(sh)换到内存的交换页数量Q单位:(x)KB/U?/span> so: 从内存(sh)换到盘的交换页数量Q单位:(x)KB/U?/span> IO bi: ?/span>块设备接受的块数Q单位:(x)?U?/span> bo: 发送到块设备的块数Q单位:(x)?U?/span> 从图中我们可以看出系l的延迟写?/span>
两者的主要差别是共享内存的大小
1.Posix׃n内存大小可通过函数ftruncate随时修改
2.System V׃n内存大小在创建时已l确定,而且最大值根据系l有所不同
Posix׃n内存
#include <sys/mman.h> QmmapQmunmapQmsyncQshm_openQshm_unlinkQ?br />
最主要的函? -- mmap
void* mmap(void* addr,size_t len,int prot,int flags,int fd,off_t offset)
函数一个句柄映到内存?sh),q个句柄可以是open的文件句柄,也可以是shm_open的共享内存区对象。当fd=-1时ؓ(f)匿名׃n内存?br /> *nix一切皆文g的观点,shm_open也是?dev/shm目录下创Z个文件对象,q回对象的描q符?br /> mmap句柄作为共享内存的底层支撑对象Q映到内存?sh),q样可以不通过read、write在进E之间共享内存。由此推一下,?nix的进E间传递数据更加原始的Ҏ(gu)是进E间d一个文件。但是频J的open、read、write、lseekpȝ调用?x)消耗过多的计算资源。所以想C(jin)这个文件句柄映到内存?sh),q样提高(sh)(jin)q程间传递数据的效率?br />
需要注意的函数 -- msync
当修改了(jin)内存映射区的内存后,内核?x)在某个时刻文件的内容更新。ؓ(f)?jin)确信文件被更新Q调用函数msync。文件的更新可以是同步(MS_SYNCQ也可以是异步(MS_ASYNCQ。(估计q里也是调用?jin)函数write更新文gQ?br />
System V׃n内存
#include <sys/shm.h> (shmget,shmat,shmdt,shmctl)
׃System V的共享内存有大小的限Ӟ所以可考虑Q用共享内存数l来解决q个问。虽然数l的大小即一个进E可以获取共享内存的数量也是有限Ӟ但是可以~解System V单个׃n内存q小的问题?img src ="http://www.shnenglu.com/range/aggbug/184665.html" width = "1" height = "1" />
]]>
]]>
用于在c串haystack中查找c串needleQ忽略大写。如果找到则q回needle串在haystack串中W一ơ出现的位置的char指针
在实际的应用中如果只加上头文Ӟ当编译时?x)出? warning: assignment makes pointer from integer without a cast
q是因ؓ(f)函数的声明在调用之后。未l声明的函数默认q回int型?/span>
因此要在#include所?/span>头文件之前加 #define _GNU_SOURCE Q以此解x(chng)问题?/span>
]]>
avgqu-sz: q_I/O队列长度。即 delta(aveq)/s/1000 (因ؓ(f)aveq的单位ؓ(f)毫秒)?/span>
]]>
?/span>~~
有几UŞ式,我所接触到的?/span>#pragma pack(n)字节寚w?/span>
取指取数的速度Q但是可能会(x)费一定的I间。在|络E序中采?/span>#pragma pack(1),不但可以减少|络量Q还可以兼容各种pȝQ不?x)因为系l对齐方式不同而导致解包错误?/span>
内存—2G
1.~译器:(x)G++ 4.5.2
2.~译器:(x)VS2010
1
2
试l果分析Q?/span>
Q是l构体内|类型大的和。但是在默认情况下,l构体的大小都是寚w字节数的倍数?/span>ubuntu只需?/span>20?/span>24是以4则是以最大的内置cd的字节数寚wQ在l构体内最大的内置cd?/span>double个字节。他们在内存?sh)的寚w方式如下图:(x)
1
2
在对齐类型的内部都是?/span>2在默认情况下Q?/span>linux4windows
1 struct complex _pack{
我们有四U情况:(x)
1. pack紧羃Q?/span>complex _pack紧羃
2. pack紧羃Q?/span>complex _pack默认
3. pack默认Q?/span>complex _pack紧羃
4. pack默认Q?/span>complex _pack默认
以下的排列均按此序?/span>
1
2
内结构体和外l构体都紧羃---- 1
2
只媄(jing)响当前结构体的变量的寚w情况Qƈ不会(x)影响l构体内部的l构体变量的排列情况。或者说#pragma pack。我们由W三U情况,内部l构体正常,外部l构体紧~,可以得出l构体的寚w是按偏移计算的?/span>
在?/span>Behavior and Classification of NAT Devices and Implications for NAT Traversal》一文中把端口映射的行为分成四U,其中包括保留端口Q不保留端口Q端口重载,端口复用。这四种分类最l区分了(jin)NAT的四U类型即Full cone NATQ?/span>Symmetric NATQ?/span>Port-Restrictes cone NAT Q?/span>Address-Restriced cone NAT?/span>
Z(jin)使覆盖网l中的节点相互通信Q我们需要进?/span>NATI越。在?/span>A NAT Traversal Mechanism for Peer-To-Peer Networks》一文种介绍?jin)根据两端不同?/span>NATcd对应的四U?/span>NATI越Ҏ(gu)。如下图
除了(jin)直接q接Q反向连接、打z和依赖都需要第三台L的帮助?/span>
在?/span>Characterization and Measurement of TCP Traversal through NATs and Firewalls》一文中介绍?/span>TCPI越的方法。在STUNT#2Ҏ(gu)中,W三C机和两台需要连接的L都有长连接,当一斚w要发hq接Ӟ向第三台L发请求,W三C机向被请求的L发送邀(g)P此时需要连接的L都向Ҏ(gu)发?/span>SYN包,此时双方的防火墙都有?jin)洞Q只要有一方的SYN包到辑֯方主机,q接׃(x)被徏立?/span>RelayҎ(gu)需要耗费的代价太大,?/span>P2P应用中一般会(x)消极的处理双斚w是对U?/span>NAT的情c(din)?/span>