ImageVerifierCode 换一换
格式:DOC , 页数:47 ,大小:818KB ,
资源ID:5972060      下载积分:10 金币
快捷注册下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

开通VIP
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.zixin.com.cn/docdown/5972060.html】到电脑端继续下载(重复下载【60天内】不扣币)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

开通VIP折扣优惠下载文档

            查看会员权益                  [ 下载后找不到文档?]

填表反馈(24小时):  下载求助     关注领币    退款申请

开具发票请登录PC端进行申请

   平台协调中心        【在线客服】        免费申请共赢上传

权利声明

1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。

注意事项

本文(分布式软件测试工具IOR源代码结构分析.doc)为本站上传会员【xrp****65】主动上传,咨信网仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知咨信网(发送邮件至1219186828@qq.com、拔打电话4009-655-100或【 微信客服】、【 QQ客服】),核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载【60天内】不扣币。 服务填表

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

1、一、 程序的功能 2 二、 程序的主要流程 3 三、 程序的主要数据结构 5 四、 程序的模块 6 4.1 词法分析模块 6 4.2 负载模块 8 4.2.1 参数介绍 10 4.2.2 重要变量 13 4.2.3 任务偏移值的产生(rankOffset) 13 4.2.5 测试文件的命名 15 4.2.6 TestIoSys函数的简要注释说明 17 4.2.7 ReduceIterResults函数的简要注释说明 21 4.2.8 SummarizeResults函数的简要注释说明 23 4.2.9 WriteOrRead函数的简要注释说明 25 4.3 底层函数

2、模块 28 4.3.1 IOR_Xfer_POSIX函数的简要注释说明 28 五、 总结 30 5.1 IOR的优点 30 5.2 IOR的缺点 30 5.3 如何修改IOR 30 六、 附录 31 6.1 每个文件的作用和信息 31 6.2重要的数据结构 32 6.3 每个c文件所包含的函数 34 6.3.1 Parse_options.c中的函数 34 6.3.2 utilities.c中的函数 36 6.3.3 aiori-POSIX.c中的函数 38 6.3.4 aiori-MPIIO.c中的函数 39 6.3.5 aiori-HDF5.c中的函数 39

3、6.3.6 aiori-NCMPI.c中的函数 39 6.3.7 IOR.c中的函数 39 一、 程序的功能 IOR是测试基准程序,它的功能是接受参数,在client上产生特定的负载,测试系统的系能,并输出测试结果。 根据IOR的功能,可以把IOR程序分成三个模块:词法分析模块、负载模块、底层函数模块。 输入的参数有三种形式: Ø 选项形式-比如 “-w –r –f –c –Z” 等 Ø 赋值形式,在-O选项后面赋值,比如“ –O api=POSIX” Ø 配置脚本形式,在配置脚本中,给参数结构体IOR_param_t成员赋值,形式如 “–f script

4、txt”使用配置脚本形式,可以设置几次测试,每次测试的参数都不一样。 IOR能模拟不同的负载,所以负载模块很复杂,其中最重要的函数TestIoSys()有400+行代码。在TestIoSys()有许多条件语句,根据参数结构体IOR_param_t里成员的值,产生不同操作。 修改IOR,减少不必要的参数,增加读写比例参数,就需要修改结构体IOR_param_t,和修改TestIoSys()函数。 二、 程序的主要流程 简略分析main函数流程,下面是main函数的不完全代码: int main(int argc, char ** argv) { IOR_queue_

5、t * tests; /*IOR_queue_t是参数结构体IOR_param_t的链表结构*/ tests = SetupTests(argc,argv); /*接受参数设置,并检查参数,然后填充参数结构体*/ While(tests != NULL) { TestIoSys(&tests->testParameters); /*根据参数结构体的成员,进行测试*/ test = test->nextTest; /*下一个测试*/ }

6、 } ParseCommandLine //词法分析命令参数,并填充参数结构体 DistributeHints //把环境变量分发到各个进程 VaildTests //检查各个参数结构体内的参数是否有效 TimeDeviation //检查每个任务之间开始时间的偏差 SeedRandGen //产生随机数 ShowTest //显示参数信息 AioriBind //装填I/O接口 ShowSetup //显示设置信息 SummarizeResults //显示测试结果 Time0 //定时器伪代码 Reduce

7、IterResults //归约操作,计算结果 三、 程序的主要数据结构 两个重要的数据结构是: aiori.h中定义的参数结构体IOR_param_t。用来填充参数。 IOR.h中定义的参数结构体队列IOR_queue_t。运行一次程序可以执行几次参数不同的测试。 typedef struct { char debug[MAX_STR]; /* debug info string */ unsigned int mode; /* file permissions */ unsigned i

8、nt openFlags; /* open flags */ int TestNum; /* test reference number */ char api[MAX_STR]; /* API for I/O */ …… int numTasks; /* number of tasks for test */ int nodes; /* number of nodes for

9、test */ int tasksPerNode; /* number of tasks per node */ int repetitions; /* number of repetitions of test */ ….. int readFile; /* read of existing file */ int writeFile; /* write of file */ …. int

10、 keepFile; /* don't delete the testfile on exit */ …. /* POSIX variables */ int singleXferAttempt; /* do not retry transfer if incomplete */ int fsYncPerWrite; /* fsync() after each write */ int fsync; /* fsync() after write */ /

11、 MPI variables */ MPI_Datatype transferType; /* datatype for transfer */ MPI_Datatype fileType; /* filetype for file view */ /* HDF5 variables */ int individualDataSets; /* datasets not shared by all procs */ int noFill; /* no fill in file creation

12、 */ IOR_offset_t setAlignment; /* alignment in bytes */ /* NCMPI variables */ int var_id; /* variable id handle for data set */ /* Lustre variables */ int lustre_stripe_count; int lustre_stripe_size; int lustre_start_ost; int lustre_ignore_locks; } IOR_param_t;

13、 typedef struct IOR_queue_t { IOR_param_t testParameters; struct IOR_queue_t * nextTest; } IOR_queue_t; 四、 程序的模块 4.1 词法分析模块 该模块包含的C文件有 Parse_options.c 该文件包括defaults.h头文件,defaults.h头文件是一个参数结构体defaultParameters的定义,该结构体包含默认的参数值。 Parse_options.c包含5个主要函数,如下表所示。 函数名 功能 ParseComm

14、andLine 对命令行参数进行词法分析 ParseLine 对一行字符串调用DecodeDirective函数进行词法分析 ReadConfigScript 读取配置脚本,分配并填充参数结构体 DecodeDirective 分析诸如“transferSize=64k”一样的偶对,并给参数结构体中的transferSize赋值。 CheckRunSettings 检查和纠正每次测试参数的参数值。 1.参数结构体中的writeFile、readFile、checkWrite、checkRead值为FALSE时,设置readFile和writeFile的值为TRUE。 2.

15、当参数结构体中的numTasks为0时,设置numTasks=MPI进程数 ParseCommandLine函数是词法分析模块的最主要的函数,它和其他函数的关系如下图 小结:参数的输入形式有三种,但对于我们编写的聚合带宽程序只需要一种输入形式,即命令行形式。所以我们只使用ParseCommandLine函数,其他函数可以删除。 4.2 负载模块 该模块包含的C文件有 IOR.C utilities.c IOR.C文件中有主函数main,SetupTests函数,TestIOSys函数,WriteOrRead函数 负载模块的函数关系图如下:

16、 4.2.1 参数介绍 编号 参数 参数作用描述 所对应的参数结构体成员 成员类型 默认值 重要程度 1 -A # 测试标志,可以在输出结果上显示,作为标记。 test reference number for easier test identification in log files TestNum 数值 -1 2 -a [POSIX|MPIIO] API接口选项 api 字符串 POSIX 重要 3 -b # 数据块大小 blockSize 数值 1048576 重要 4 -B 用于POSIX接口,使用直接I/

17、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选项一起使用

18、当>0时,每次循环的随机种子都一样,当<0时,每次循环的随机种子都不一样。 reorderTasksRandomSeed 数值 0 一般 10 -d # 每次循环间的延迟时间 interTestDelay 数值 0 11 -D # 每次读写操作的限定时长。数值0表示关闭该选项。 deadlineForStonewalling 数值 0 12 -Y 每次POSIX write操作后都执行同步sync。 fsYncPerWrite 布尔 0 一般 13 -e 每次循环都执行同步sync。 fsync 布尔 0 一般 14 -

19、E 每次写访问前不删除已经存在的文件(使用已经存在的文件)。 useExistingTestFile 布尔 0 15 -f S 配置文件的名字。 16 -F 并发模式(file-per-process) filePerProc 布尔 0 重要 17 -g 所用任务同步进行打开文件操作,同步进行写操作,同步进行读操作,同步进行关闭操作。 use barriers between open, write/read, and close intraTestBarriers 布尔 0 18 -G # 设置时间戳 setTime

20、StampSignature 数值 0 19 -h 显示帮助文件 showHelp 布尔 0 需要 20 -H 显示提示。 show hints(mpi可能会根据hints进行优化操作,提高性能) showHints 布尔 21 -i # 每次测试的循环次数。 repetitions 数值 1 重要 22 -j # 显示哪个进程操作时间已经超出了平均操作时间#秒。数值0表示不使用该选项。 outlierThreshold 数值 0 23 -J # 设置HDF5数据对齐。 setAlignment 字符串 1

21、 24 -k 退出程序后,不删除测试文件。 keepFile 布尔 0 25 -K 数据检查后,保留错误的文件。(通过设置,可以在读写操作后,进行数据检查) keepFileWithError 布尔 0 26 -l 把文件偏移值写到文件中。 use file offset as stored signature storeFileOffset 布尔 0 27 -m 使用循环次序号作为测试文件名字的一部分。也就是每次循环都创建新的文件。 multiFile 布尔 0 一般 28 -n 创建HDF5文件时不填充。 noFill

22、 布尔 0 29 -N # IOR任务数,当IOR任务数大于MPI任务数时,IOR任务数被设定为MPI任务数的值。数值0表示IOR任务数等于MPI任务数。 numTasks 数值 0 重要 30 -o S 测试文件的名字。注意:在filePerProc被设置的情况下,各个任务会取用多文件名下的单文件名‘-o S1@S2@S3 ’。取用的方式是循环取用。如任务0使用的测试文件名字是‘S1’,任务1使用的测试文件名字是‘S2’,任务2使用的测试文件名诗‘S3’,任务3使用的测试文件名是‘S1’,任务4…… S1、S2、S3可以是不同文件系统下的文件名。 testF

23、ileName 字符串 testFile 重要 31 -O S IOR指令字符串。 32 -p 预先分配文件空间。(对于MPI) preallocate 布尔 0 重要 33 -q 当出现文件检查错误时,退出。 quitOnError 布尔 0 34 -r 读文件 readFile 布尔 1 重要 35 -R 读文件后,再读一次,检查是否出错。(数据检查) checkRead 布尔 0 36 -s 文件段数。 segmentCount 数值 1 重要 37 -t 传输大小 transf

24、erSize 数值 262144 重要 38 -T # 设定测试时间最大值。数值0表示关闭该选项。 maxTimeDuration 数值 0 39 -u 对于并发模式,每个任务使用一个工作目录。 uniqueDir 布尔 0 一般 40 -U 提示文件的文件名(包含很多hints,传递hints到程序中,并设置hints,hints作为许多MPI操作函数的参数,影响MPI I/O的性能) full name for hints file hintsFileName 字符串 41 -v 输出结果。 verbose 数值 0

25、 42 -V 使用MPI_File_set_view(MPI中) use MPI_File_set_view useFileView 布尔 一般 43 -w 写文件 writeFile 布尔 1 重要 44 -W 写文件后,读回文件,检查是否出错。(数据检查) checkWrite 布尔 0 45 -x 假如传输出错,不再次进行传输。 singleXferAttempt 布尔 一般 46 -z 随机偏移(randomOffset),也就是随机访问。 access is to random, not sequential, o

26、ffsets within a file 该选项与一下选项不可兼容: checkRead storeFileOffset MPIIO collective of useFileView HDF5 or NCMPI randomOffset 布尔 0 一般 4.2.2 重要变量 extern IOR_param_t defaultParameters, initialTestParams; extern int errno; /* error numb

27、er */ extern char ** environ; int totalErrorCount = 0; int numTasksWorld = 0; /*一共有多少个任务*/ int rank = 0; /*任务编号*/ int rankOffset = 0; /*任务偏移值*/ int tasksPerNode = 0; /* tasks per node */ int

28、 verbose = VERBOSE_0; /* verbose output */ double wall_clock_delta = 0; double wall_clock_deviation; MPI_Comm testComm; 4.2.3 任务偏移值的产生(rankOffset) 任务偏移值(rankOffset)的作用是,当任务读文件时,任务会读第(rank+rankOffset)%test->numTasks任务所写的文件。 以下代码是TestIoSys函数中的部分代

29、码,作用是产生任务偏移值 …… /* *读文件,并在每次I/O操作间计时。 */ if (test->readFile && (maxTimeDuration ? (GetTimeStamp() - startTime < maxTimeDuration) : 1)) { /*基于 -C,-Z,-Q,-X 选项,每个任务为读操作产生任务偏移值*/ /*当设置-C –Q选项时,产生的任务偏移值是常量*/ if (test->reorderTasks) { rankOffset = (test->taskPerNodeOffset*test->tasksPerNode) %

30、 test->numTasks; } /* 当设置-Z –Q (-X)选项时,产生的任务偏移值是随机的*/ if (test->reorderTasksRandom) { /*以下操作不会与文件偏移值(-Z选项)冲突,因为GetOffsetArrayRandom函数产生文件偏移值 */ int *rankoffs, *filecont, *filehits, ifile, jfile, nodeoffset; unsigned int iseed0; nodeoffset = test->taskPerNodeOffset; nodeoff

31、set = (nodeoffset < test->nodes) ? nodeoffset : test->nodes-1; iseed0= (test->reorderTasksRandomSeed < 0) ? (-1*test->reorderTasksRandomSeed+rep):test->reorderTasksRandomSeed; srand(rank+iseed0); rankOffset = rand() % test->numTasks; while (rankOffset < (nodeoffset*tes

32、t->tasksPerNode)) { rankOffset = rand() % test->numTasks; } …… } 4.2.5 测试文件的命名 每个任务调用GetTestFileName函数就能得到测试文件的文件名。测试文件的文件名与参数结构体变量中成员(filePerProc、uniqueDir、multiFile、repCounter)有关。 以下是GetTestFileName的源代码: void GetTestFileName(char * testFileName, IOR_param_t * test) {

33、 char ** fileNames, initialTestFileName[MAXPATHLEN], testFileNameRoot[MAX_STR], tmpString[MAX_STR]; int count; strcpy(initialTestFileName, test->testFileName); fileNames = ParseFileName(initialTestFileName, &count); /*1*/ if

34、count > 1 && test->uniqueDir == TRUE) /*2*/ ERR("cannot use multiple file names with unique directories"); if (test->filePerProc) /*3*/ { strcpy(testFileNameRoot, fileNames[((rank+rankOffset)%test->numTasks) % count]); /*4*/ } else { strcpy(testFileNa

35、meRoot, fileNames[0]); /*5*/ } /* give unique name if using multiple files */ if (test->filePerProc) /*6*/ { /** prepend rank subdirectory before filename, e.g., /dir/file => /dir//file*/ if (test->uniqueDir == TRUE)

36、 /*7*/ { strcpy(testFileNameRoot, PrependDir(test, testFileNameRoot)); /*8*/ } sprintf(testFileName, "%s.%08d", testFileNameRoot, (rank+rankOffset)%test->numTasks); /*9*/ } else { strcpy(testFileName, testFileName

37、Root); /*10*/ } /* add suffix for multiple files */ if (test->repCounter > -1) /*11*/ { sprintf(tmpString, ".%d", test->repCounter); strcat(testFileName, tmpString); /*12*/ } } /* GetTestFileName() */ 为了便于分析,我们设num=(rank+rankOffset

38、)%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时,给测试文

39、件名加上后缀,后缀是循环序号。 当count=1时,testFileName=” /mnt/testfs”,各个任务的测试文件名如下: count=1 uniqueDir=1 uniqueDir=0 filePerProc = 1 multiFile=1 /mnt//testfs.. /mnt/testfs.. multiFile=0 /mnt//testfs. /mnt/testfs. filePerProc = 0 (Single shared file) multiFile=1

40、/mnt/testfs. multiFile=0 /mnt/testfs 4.2.6 TestIoSys函数的简要注释说明 void TestIoSys(IOR_param_t *test) { char testFileName[MAX_STR]; double * timer[12]; double startTime; int i, rep, maxTimeDuration; void

41、 * fd; MPI_Group orig_group, new_group; int range[3]; IOR_offset_t dataMoved; /* for data rate calculation */ /*创建测试所需要的通信域(MPI)*/ …… /*求出每个节点的任务数*/ test->tasksPerNode = CountTasksPerNode(test->numTasks, testComm); /*初始化计时数组*/ …… /*初始化每次循环用于保存结果

42、的数组*/ …… /*bind I/O calls to specific API */ AioriBind(test->api); /*计算聚合文件的大小*/ for (rep = 0; rep < test->repetitions; rep++) { test->aggFileSizeFromCalc[rep] = test->blockSize * test->segmentCount * test->numTasks; } /*记录开始时间*/ startTime = GetT

43、imeStamp(); /*循环测试,每个循环中有四种主要操作:写文件、检查写、读文件、检查读*/ for (rep = 0; rep < test->repetitions; rep++) { /*每次循环测试由任务0记录开始时间,并向所有任务广播*/ …… /* 使用循环序号作为测试文件名的一部分,影响GetTestFileName 函数的结果*/ if (test->multiFile) test->repCounter = rep; /*写文件,并计时*/ if (test->writeFile) { GetTestFileNa

44、me(testFileName, test); DelaySecs(test->interTestDelay); if (test->useExistingTestFile == FALSE) RemoveFile(testFileName, test->filePerProc, test); MPI_CHECK(MPI_Barrier(testComm), "barrier error"); test->open = WRITE; timer[0][rep] = GetTimeStamp(); fd = IOR_

45、Create(testFileName, test); timer[1][rep] = GetTimeStamp(); if (test->intraTestBarriers) MPI_CHECK(MPI_Barrier(testComm), "barrier error"); timer[2][rep] = GetTimeStamp(); dataMoved = WriteOrRead(test, fd, WRITE); timer[3][rep] = GetTimeStamp(); if (test

46、>intraTestBarriers) MPI_CHECK(MPI_Barrier(testComm), "barrier error"); timer[4][rep] = GetTimeStamp(); IOR_Close(fd, test); timer[5][rep] = GetTimeStamp(); MPI_CHECK(MPI_Barrier(testComm), "barrier error"); /* get the size of the file just written */ t

47、est->aggFileSizeFromStat[rep] = IOR_GetFileSize(test, testComm, testFileName); /* check if stat() of file doesn't equal expected file size, use actual amount of byte moved */ CheckFileSize(test, dataMoved, rep); ReduceIterResults(test, timer, rep, WRITE);

48、 if (test->outlierThreshold) CheckForOutliers(test, timer, rep, WRITE); }/*if writeFile*/ /*检查写操作*/ if (test->checkWrite) { MPI_CHECK(MPI_Barrier(testComm), "barrier error"); if (test->corruptFile) CorruptFile(testFileName, test, rep, WRITECHECK); MPI_CHECK(MP

49、I_Barrier(testComm), "barrier error"); if (test->reorderTasks) rankOffset = (2*test->tasksPerNode) % test->numTasks; GetTestFileName(testFileName, test); test->open = WRITECHECK; fd = IOR_Open(testFileName, test); dataMoved = WriteOrRead(test, fd, WRITECHECK); IOR_Clos

50、e(fd, test); rankOffset = 0; } /*读文件,并计时*/ if (test->readFile) { /*产生任务偏移值*/ …… GetTestFileName(testFileName, test); DelaySecs(test->interTestDelay); MPI_CHECK(MPI_Barrier(testComm), "barrier error"); test->open = READ; timer[6][rep] = GetTimeStamp(); fd = IOR_Open

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服