6
15
2014
1

blktrace 测试结果分析

在上一篇blktrace测试中,我们的测试函数通过getpid函数得到运行程序的进程号。而blktrace的捕捉结果的第五列为进程号。可以通过分析第五列为对应进程号的所有行从而得到该进程在执行过程中的所有动作。测试结果分析程序的代码如下。

该代码输入两个参数:参数一:代分析结果文件的文件名;参数二:进程号

#include"stdio.h"
#include"string.h"
#include"stdlib.h"

void main(int argc,char *argv[])
{
	FILE *src=NULL;
	FILE *des=NULL;
	long COUNT=0;
	int des_pid;
	char inputfile[200]="",outputfile[200]="", temp[1000];
	sprintf(inputfile,"/home/share/6-13/fread_first/%s",argv[1]);
	sprintf(outputfile,"/home/share/6-13/fread_first/interval-%s",argv[1]);
	des_pid=atoi(argv[2]);
	printf("%s\t%s\n",inputfile,outputfile);
	if((src = fopen(inputfile,"r"))<=0)
	{
		printf("open error1!\n");
	}	
	if((des = fopen(outputfile,"w"))<=0)
	{
		printf("open error2!\n");
	}
	char major_minor[10],cpu_id[30],sequence_number[20],time[20],process_id[20],action[10],RWBS[10],detail[200];
	char last_major_minor[10],last_cpu_id[30],last_sequence_number[20],last_time[20],last_process_id[20],last_action[10],last_RWBS[10],last_detail[200];
	
	double t,lasttime,interval,TIME[30],total_time=0.0;
	int last_pid,i;
	for(i=0;i<30;i++)TIME[i]=0.0;
	fgets(temp,200,src);
	//sscanf最后一个输入所有没有读入的
	sscanf(temp,"%s%s%s%s%s%s%s%[^\n]",last_major_minor,last_cpu_id,last_sequence_number,last_time,last_process_id,last_action,last_RWBS,last_detail);
	t=lasttime=atof(time);
	last_pid=atoi(last_process_id);
    //统计pid为对应程序运行pid的动作,并统计不同动作的时间
	while(fgets(temp,1000,src)!=NULL)
	{
		sscanf(temp,"%s%s%s%s%s%s%s%[^\n]",major_minor,cpu_id,sequence_number,time,process_id,action,RWBS,detail);
	    printf("%s %s %s %s %s %s %s %s\n",major_minor,cpu_id,sequence_number,time,process_id,action,RWBS,detail);
		t=atof(time);
		if(last_pid==des_pid)
		{		
		interval=t-lasttime;
		fprintf(des,"%s %s %s %.10lf %s %s %s %s\n",last_major_minor,last_cpu_id,last_sequence_number,interval,last_process_id,last_action,last_RWBS,last_detail);
	    if(!strcmp("A",last_action))TIME['A'-'A'] = TIME['A'-'A']+interval;
		else if(!strcmp("Q",last_action))TIME['Q'-'A'] = TIME['Q'-'A']+interval;
		else if(!strcmp("D",last_action))TIME['D'-'A'] = TIME['D'-'A']+interval;
		else if(!strcmp("G",last_action))TIME['G'-'A'] = TIME['G'-'A']+interval;
		else if(!strcmp("P",last_action))TIME['P'-'A'] = TIME['P'-'A']+interval;
		else if(!strcmp("I",last_action))TIME['I'-'A'] = TIME['I'-'A']+interval;
		else if(!strcmp("M",last_action))TIME['M'-'A'] = TIME['M'-'A']+interval;
		else if(!strcmp("C",last_action))TIME['C'-'A'] = TIME['C'-'A']+interval;
		else if(!strcmp("B",last_action))TIME['B'-'A'] = TIME['B'-'A']+interval;
		else if(!strcmp("F",last_action))TIME['F'-'A'] = TIME['F'-'A']+interval;
		else if(!strcmp("S",last_action))TIME['S'-'A'] = TIME['S'-'A']+interval;
		else if(!strcmp("U",last_action))TIME['U'-'A'] = TIME['U'-'A']+interval;
		else if(!strcmp("T",last_action))TIME['T'-'A'] = TIME['T'-'A']+interval;
		else if(!strcmp("X",last_action))TIME['X'-'A'] = TIME['X'-'A']+interval;
		else if(!strcmp("m",last_action))TIME[26] = TIME[26]+interval;
		else if(!strcmp("UT",last_action))TIME[27] = TIME[27]+interval;
		else printf("A state we do not expect: %s !!!!!!!!!!!\n",last_action);
		COUNT++;
		}
		last_pid=atoi(process_id);		
		
		strcpy(last_major_minor,major_minor);
		strcpy(last_cpu_id,cpu_id);
		strcpy(last_sequence_number,sequence_number);
		strcpy(last_process_id,process_id);
		strcpy(last_action,action);
		strcpy(last_RWBS,RWBS);
		strcpy(last_detail,detail);	
		lasttime=t;
	}
	//输出每个动作的时间
	for(i=0;i<26;i++){
		if(TIME[i]!=0)
		{fprintf(des,"%c = %.10lf\n",'A'+i,TIME[i]);
		total_time=total_time+TIME[i];}
	}
	if(TIME[26]!=0){fprintf(des,"m = %.10lf\n",TIME[26]);total_time=total_time+TIME[i];}
	if(TIME[27]!=0){fprintf(des,"UT = %.10lf\n",TIME[27]);total_time=total_time+TIME[i];}
	fprintf(des,"total_time=%10lf",total_time);
	printf("%ld\n",COUNT);
	fclose(src);
	fclose(des);
}

通过上述代码,我们可以得到不同动作的时间TIME[i],以及该进程所有动作的总时间total_time。上述代码通过fprint函数把所有的进程号为测试程序进程号对应行的动作输出到文件中。下面看测试结果。

测试环境:

虚拟机 Linux2.6.34.14 ,i686

 

测试结果1:fopen-fgets-fclose测试

fgets对象的大小为61M,运行函数得到测试函数(上篇所属)的测试进程号,通过测试结果分析函数分析,得到统计结果,一下是不同动作的运行总时间:

A = 0.0170144810
C = 0.0015857350
D = 0.8192398520
G = 0.0135601120
I = 0.0089563970
P = 0.0069398190
Q = 0.0149995750
U = 0.0730064410
UT = 0.0011541530

 

由上述测试结果我们可以看出,在fgets这个动作中,耗时最大的是D,接下来是U A Q G。通过官方文档我们可以看到这几个动作代表的具体含义:

D- issud A request that previously resided on the block layer queue or in the io scheduler has been sent to the driver.一个原本属于通用块层或者io调度层的请求下发到设备驱动层。

A- remap For stacked devices,incoming io is remapped to device below it in the io stack.The remap action details what exactly being remapped to what.地址进行重新映射,找到请求的具体地址

Q- queued This notes intent to queue io at the given location.No real requests exist yet.将io请求在一个指定的地方排队,目前没有真实的io请求。

U- unplug Some request data already queued in the device ,start sending requests to the driver.This may happen automatically if a timeout period has passed or if a number of requests has been added to the queue.

G- get request To send any type of request to a block device, a struct request container must be allocate first. 用request结构来包装请求。

P- plug When io is queued to a previously empty block device queue,Linux will plug the queue in anticipation of future ios being added before this data is needed.当io在一个之前为空的设备上排队,linux会阻塞这个队列

C- complete A previously issued request has been completed.The output will detail the sector and size of that request,as well as the success or failure of it. 上一个请求的完成。输出结果详细说明了请求的扇区和大小,以及该请求成功或者是失败。

 

测试结果2:fopen-fread-fclose

fread文件的大小为61M,通过以上相同的方法得到分析结果,下面给出不同操作的时间:

A = 0.0107872850
C = 0.0007980870
D = 0.8660075290
G = 0.0136940280
I = 0.0082448260
P = 0.0067011250
Q = 0.0113347330
U = 0.0602230790
UT = 0.0012564270

以上不同动作的延时由大到小分别是D U G Q A.这几项的含义见上

 

测试结果3:fopen-fprintf-fclose

fprintf(des,"test\n");输出10000000次。统计输出结果

A = 0.7363318950
C = 0.0218782530
D = 0.0114673100
G = 0.0274727540
I = 0.0063651330
M = 0.8235856390
P = 0.0042055460
Q = 0.7142546430
U = 0.0020267710
UT = 0.0248391280
 
fprintf函数中,不同动作时间消耗排序为M A Q G
M- back merge A previously inserted reuqest exists that end on the boundary of where this io begins,so the io scheduler can merge them together. io调度器把io地址相邻位置的请求合并在一起。
 
T- unplug due to timer If nobody requests the io that was queued after plugging the queue, Linux will automatically unplug it after a defined perod has passed.
 
Category: blktrace | Tags: | Read Count: 2844
Avatar_small
AP 10th Maths Model 说:
2022年9月11日 16:01

Mathematics is one of the tough subjects and also an easy subject for class 10th standard students of TM, EM, AP 10th Maths Model Paper UM and HM studying at government and private schools of the state. Department of School Education and teaching staff of various institutions have designed and suggested the Mathematics question paper with solutions for all chapters topic wide for each lesson of the course, and the AP SSC Maths Model Paper 2023 Pdf designed based on the new revised syllabus and curriculum.


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com