分布式软件测试工具IOR源代码结构分析.docx

上传人:b****3 文档编号:12660656 上传时间:2023-04-21 格式:DOCX 页数:66 大小:227.95KB
下载 相关 举报
分布式软件测试工具IOR源代码结构分析.docx_第1页
第1页 / 共66页
分布式软件测试工具IOR源代码结构分析.docx_第2页
第2页 / 共66页
分布式软件测试工具IOR源代码结构分析.docx_第3页
第3页 / 共66页
分布式软件测试工具IOR源代码结构分析.docx_第4页
第4页 / 共66页
分布式软件测试工具IOR源代码结构分析.docx_第5页
第5页 / 共66页
点击查看更多>>
下载资源
资源描述

分布式软件测试工具IOR源代码结构分析.docx

《分布式软件测试工具IOR源代码结构分析.docx》由会员分享,可在线阅读,更多相关《分布式软件测试工具IOR源代码结构分析.docx(66页珍藏版)》请在冰豆网上搜索。

分布式软件测试工具IOR源代码结构分析.docx

分布式软件测试工具IOR源代码结构分析

一、程序的功能

IOR是测试基准程序,它的功能是接受参数,在client上产生特定的负载,测试系统的系能,并输出测试结果。

根据IOR的功能,可以把IOR程序分成三个模块:

词法分析模块、负载模块、底层函数模块。

输入的参数有三种形式:

Ø选项形式-比如“-w–r–f–c–Z”等

Ø赋值形式,在-O选项后面赋值,比如“–Oapi=POSIX”

Ø配置脚本形式,在配置脚本中,给参数结构体IOR_param_t成员赋值,形式如“–fscript.txt”使用配置脚本形式,可以设置几次测试,每次测试的参数都不一样。

IOR能模拟不同的负载,所以负载模块很复杂,其中最重要的函数TestIoSys()有400+行代码。

在TestIoSys()有许多条件语句,根据参数结构体IOR_param_t里成员的值,产生不同操作。

修改IOR,减少不必要的参数,增加读写比例参数,就需要修改结构体IOR_param_t,和修改TestIoSys()函数。

二、程序的主要流程

简略分析main函数流程,下面是main函数的不完全代码:

intmain(intargc,char**argv)

{

IOR_queue_t*tests;/*IOR_queue_t是参数结构体IOR_param_t的链表结构*/

tests=SetupTests(argc,argv);/*接受参数设置,并检查参数,然后填充参数结构体*/

While(tests!

=NULL)

{

TestIoSys(&tests->testParameters);/*根据参数结构体的成员,进行测试*/

test=test->nextTest;/*下一个测试*/

}

}

ParseCommandLine//词法分析命令参数,并填充参数结构体

DistributeHints//把环境变量分发到各个进程

VaildTests//检查各个参数结构体内的参数是否有效

TimeDeviation//检查每个任务之间开始时间的偏差

SeedRandGen//产生随机数

ShowTest//显示参数信息

AioriBind//装填I/O接口

ShowSetup//显示设置信息

SummarizeResults//显示测试结果

Time0//定时器伪代码

ReduceIterResults//归约操作,计算结果

三、程序的主要数据结构

两个重要的数据结构是:

aiori.h中定义的参数结构体IOR_param_t。

用来填充参数。

IOR.h中定义的参数结构体队列IOR_queue_t。

运行一次程序可以执行几次参数不同的测试。

typedefstruct

{

chardebug[MAX_STR];/*debuginfostring*/

unsignedintmode;/*filepermissions*/

unsignedintopenFlags;/*openflags*/

intTestNum;/*testreferencenumber*/

charapi[MAX_STR];/*APIforI/O*/

……

intnumTasks;/*numberoftasksfortest*/

intnodes;/*numberofnodesfortest*/

inttasksPerNode;/*numberoftaskspernode*/

intrepetitions;/*numberofrepetitionsoftest*/

…..

intreadFile;/*readofexistingfile*/

intwriteFile;/*writeoffile*/

….

intkeepFile;/*don'tdeletethetestfileonexit*/

….

/*POSIXvariables*/

intsingleXferAttempt;/*donotretrytransferifincomplete*/

intfsYncPerWrite;/*fsync()aftereachwrite*/

intfsync;/*fsync()afterwrite*/

/*MPIvariables*/

MPI_DatatypetransferType;/*datatypefortransfer*/

MPI_DatatypefileType;/*filetypeforfileview*/

/*HDF5variables*/

intindividualDataSets;/*datasetsnotsharedbyallprocs*/

intnoFill;/*nofillinfilecreation*/

IOR_offset_tsetAlignment;/*alignmentinbytes*/

/*NCMPIvariables*/

intvar_id;/*variableidhandlefordataset*/

/*Lustrevariables*/

intlustre_stripe_count;

intlustre_stripe_size;

intlustre_start_ost;

intlustre_ignore_locks;

}IOR_param_t;

typedefstructIOR_queue_t{

IOR_param_ttestParameters;

structIOR_queue_t*nextTest;

}IOR_queue_t;

四、程序的模块

4.1词法分析模块

该模块包含的C文件有

Parse_options.c

该文件包括defaults.h头文件,defaults.h头文件是一个参数结构体defaultParameters的定义,该结构体包含默认的参数值。

Parse_options.c包含5个主要函数,如下表所示。

函数名

功能

ParseCommandLine

对命令行参数进行词法分析

ParseLine

对一行字符串调用DecodeDirective函数进行词法分析

ReadConfigScript

读取配置脚本,分配并填充参数结构体

DecodeDirective

分析诸如“transferSize=64k”一样的偶对,并给参数结构体中的transferSize赋值。

CheckRunSettings

检查和纠正每次测试参数的参数值。

1.参数结构体中的writeFile、readFile、checkWrite、checkRead值为FALSE时,设置readFile和writeFile的值为TRUE。

2.当参数结构体中的numTasks为0时,设置numTasks=MPI进程数

ParseCommandLine函数是词法分析模块的最主要的函数,它和其他函数的关系如下图

小结:

参数的输入形式有三种,但对于我们编写的聚合带宽程序只需要一种输入形式,即命令行形式。

所以我们只使用ParseCommandLine函数,其他函数可以删除。

4.2负载模块

该模块包含的C文件有

IOR.C

utilities.c

IOR.C文件中有主函数main,SetupTests函数,TestIOSys函数,WriteOrRead函数

负载模块的函数关系图如下:

4.2.1参数介绍

编号

参数

参数作用描述

所对应的参数结构体成员

成员类型

默认值

重要程度

1

-A#

测试标志,可以在输出结果上显示,作为标记。

testreferencenumberforeasiertestidentificationinlogfiles

TestNum

数值

-1

2

-a[POSIX|MPIIO]

API接口选项

api

字符串

POSIX

重要

3

-b#

数据块大小

blockSize

数值

1048576

重要

4

-B

用于POSIX接口,使用直接I/O,不使用I/O缓存。

useO_DIRECT

布尔

0

一般

5

-c

聚合(collective)I/O,MPI的文件操作为组调用

collective

布尔

0

一般

6

-C

读操作时,读取其他任务所写的文件。

所有任务的任务偏移量是常量。

reorderTasks

布尔

0

一般

7

-Q#

任务偏移量,用于-C–Z选项

taskPerNodeOffset

数值

1

一般

8

-Z

所有任务的任务偏移量不是常量,是随机产生的。

reorderTasksRandom

布尔

0

一般

9

-X#

与-Z选项一起使用。

当>0时,每次循环的随机种子都一样,当<0时,每次循环的随机种子都不一样。

reorderTasksRandomSeed

数值

0

一般

10

-d#

每次循环间的延迟时间

interTestDelay

数值

0

11

-D#

每次读写操作的限定时长。

数值0表示关闭该选项。

deadlineForStonewalling

数值

0

12

-Y

每次POSIXwrite操作后都执行同步sync。

fsYncPerWrite

布尔

0

一般

13

-e

每次循环都执行同步sync。

fsync

布尔

0

一般

14

-E

每次写访问前不删除已经存在的文件(使用已经存在的文件)。

useExistingTestFile

布尔

0

15

-fS

配置文件的名字。

16

-F

并发模式(file-per-process)

filePerProc

布尔

0

重要

17

-g

所用任务同步进行打开文件操作,同步进行写操作,同步进行读操作,同步进行关闭操作。

usebarriersbetweenopen,write/read,andclose

intraTestBarriers

布尔

0

18

-G#

设置时间戳

setTimeStampSignature

数值

0

19

-h

显示帮助文件

showHelp

布尔

0

需要

20

-H

显示提示。

showhints(mpi可能会根据hints进行优化操作,提高性能)

showHints

布尔

21

-i#

每次测试的循环次数。

repetitions

数值

1

重要

22

-j#

显示哪个进程操作时间已经超出了平均操作时间#秒。

数值0表示不使用该选项。

outlierThreshold

数值

0

23

-J#

设置HDF5数据对齐。

setAlignment

字符串

1

24

-k

退出程序后,不删除测试文件。

keepFile

布尔

0

25

-K

数据检查后,保留错误的文件。

(通过设置,可以在读写操作后,进行数据检查)

keepFileWithError

布尔

0

26

-l

把文件偏移值写到文件中。

usefileoffsetasstoredsignature

storeFileOffset

布尔

0

27

-m

使用循环次序号作为测试文件名字的一部分。

也就是每次循环都创建新的文件。

multiFile

布尔

0

一般

28

-n

创建HDF5文件时不填充。

noFill

布尔

0

29

-N#

IOR任务数,当IOR任务数大于MPI任务数时,IOR任务数被设定为MPI任务数的值。

数值0表示IOR任务数等于MPI任务数。

numTasks

数值

0

重要

30

-oS

测试文件的名字。

注意:

在filePerProc被设置的情况下,各个任务会取用多文件名下的单文件名‘-oS1@S2@S3’。

取用的方式是循环取用。

如任务0使用的测试文件名字是‘S1’,任务1使用的测试文件名字是‘S2’,任务2使用的测试文件名诗‘S3’,任务3使用的测试文件名是‘S1’,任务4……

S1、S2、S3可以是不同文件系统下的文件名。

testFileName

字符串

testFile

重要

31

-OS

IOR指令字符串。

32

-p

预先分配文件空间。

(对于MPI)

preallocate

布尔

0

重要

33

-q

当出现文件检查错误时,退出。

quitOnError

布尔

0

34

-r

读文件

readFile

布尔

1

重要

35

-R

读文件后,再读一次,检查是否出错。

(数据检查)

checkRead

布尔

0

36

-s

文件段数。

segmentCount

数值

1

重要

37

-t

传输大小

transferSize

数值

262144

重要

38

-T#

设定测试时间最大值。

数值0表示关闭该选项。

maxTimeDuration

数值

0

39

-u

对于并发模式,每个任务使用一个工作目录。

uniqueDir

布尔

0

一般

40

-U

提示文件的文件名(包含很多hints,传递hints到程序中,并设置hints,hints作为许多MPI操作函数的参数,影响MPII/O的性能)

fullnameforhintsfile

hintsFileName

字符串

41

-v

输出结果。

verbose

数值

0

42

-V

使用MPI_File_set_view(MPI中)

useMPI_File_set_view

useFileView

布尔

一般

43

-w

写文件

writeFile

布尔

1

重要

44

-W

写文件后,读回文件,检查是否出错。

(数据检查)

checkWrite

布尔

0

45

-x

假如传输出错,不再次进行传输。

singleXferAttempt

布尔

一般

46

-z

随机偏移(randomOffset),也就是随机访问。

accessistorandom,notsequential,offsetswithinafile

该选项与一下选项不可兼容:

checkRead

storeFileOffset

MPIIOcollectiveofuseFileView

HDF5orNCMPI

randomOffset

布尔

0

一般

4.2.2重要变量

externIOR_param_tdefaultParameters,

initialTestParams;

externinterrno;/*errornumber*/

externchar**environ;

inttotalErrorCount=0;

intnumTasksWorld=0;/*一共有多少个任务*/

intrank=0;/*任务编号*/

intrankOffset=0;/*任务偏移值*/

inttasksPerNode=0;/*taskspernode*/

intverbose=VERBOSE_0;/*verboseoutput*/

doublewall_clock_delta=0;

doublewall_clock_deviation;

MPI_CommtestComm;

4.2.3任务偏移值的产生(rankOffset)

任务偏移值(rankOffset)的作用是,当任务读文件时,任务会读第(rank+rankOffset)%test->numTasks任务所写的文件。

以下代码是TestIoSys函数中的部分代码,作用是产生任务偏移值

……

/*

*读文件,并在每次I/O操作间计时。

*/

if(test->readFile&&(maxTimeDuration?

(GetTimeStamp()-startTime

1)){

/*基于-C,-Z,-Q,-X选项,每个任务为读操作产生任务偏移值*/

/*当设置-C–Q选项时,产生的任务偏移值是常量*/

if(test->reorderTasks)

{

rankOffset=(test->taskPerNodeOffset*test->tasksPerNode)%test->numTasks;

}

/*当设置-Z–Q(-X)选项时,产生的任务偏移值是随机的*/

if(test->reorderTasksRandom)

{

/*以下操作不会与文件偏移值(-Z选项)冲突,因为GetOffsetArrayRandom函数产生文件偏移值*/

int*rankoffs,*filecont,*filehits,ifile,jfile,nodeoffset;

unsignedintiseed0;

nodeoffset=test->taskPerNodeOffset;

nodeoffset=(nodeoffsetnodes)?

nodeoffset:

test->nodes-1;

iseed0=(test->reorderTasksRandomSeed<0)?

(-1*test->reorderTasksRandomSeed+rep):

test->reorderTasksRandomSeed;

srand(rank+iseed0);

rankOffset=rand()%test->numTasks;

while(rankOffset<(nodeoffset*test->tasksPerNode))

{

rankOffset=rand()%test->numTasks;

}

……

}

 

4.2.5测试文件的命名

每个任务调用GetTestFileName函数就能得到测试文件的文件名。

测试文件的文件名与参数结构体变量中成员(filePerProc、uniqueDir、multiFile、repCounter)有关。

以下是GetTestFileName的源代码:

voidGetTestFileName(char*testFileName,IOR_param_t*test)

{

char**fileNames,

initialTestFileName[MAXPATHLEN],

testFileNameRoot[MAX_STR],

tmpString[MAX_STR];

intcount;

strcpy(initialTestFileName,test->testFileName);

fileNames=ParseFileName(initialTestFileName,&count);/*1*/

if(count>1&&test->uniqueDir==TRUE)/*2*/

ERR("cannotusemultiplefilenameswithuniquedirectories");

if(test->filePerProc)/*3*/

{

strcpy(testFileNameRoot,fileNames[((rank+rankOffset)%test->numTasks)%count]);/*4*/

}

else

{

strcpy(testFileNameRoot,fileNames[0]);/*5*/

}

/*giveuniquenameifusingmultiplefiles*/

if(test->filePerProc)/*6*/

{

/**prependranksubdirectorybeforefilename,e.g.,/dir/file=>/dir//file*/

if(test->uniqueDir==TRUE)/*7*/

{

strcpy(testFileNameRoot,PrependDir(test,testFileNameRoot));/*8*/

}

sprintf(testFileName,"%s.%08d",testFileNameRoot,

(rank+rankOffset)%test->numTasks);/*9*/

}

else

{

strcpy(testFileName,testFileNameRoot);/*10*/

}

/*addsuffixformultiplefiles*/

if(test->repCounter>-1)/*11*/

{

sprintf(tmpString,".%d",test->repCounter);

strcat(testFileName,tmpString);/*12*/

}

}/*GetTestFileName()*/

为了便于分析,我们设num=(rank+rankOffset)%test->numTasks。

在第1行中,ParseFileName函数对参数结构体中成员testFileName进行词法分析,比如当testFileName=”/tmp/myfs@/mnt/testfs@/mnt/nfs”时,fileNames[0]=”/tmp/myfs”,fileNames[1]=”/mnt/testfs”,fileNames[2]=”/mnt/nfs”。

第8行中,PrependDir函数能把”/mnt/testfs”变成”/mnt//testfs”。

第11行中,当设置-m选项时,即参数结构体成员multiFile被设置为1时,给测试文件名加上后缀,后缀是循环序号。

当count=1时,testFileName=

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1