如果您无法下载资料,请参考说明:
1、部分资料下载需要金币,请确保您的账户上有足够的金币
2、已购买过的文档,再次下载不重复扣费
3、资料包下载后请先用软件解压,在使用对应软件打开
10001XINU环境高级编程下载表5-4使用标准O/I例程得到的时间结果函数用户UPC(秒)系统UPC(秒)时钟时间(秒)程序正文字节数表1-3中的最佳时间0.03.03.0fgets,fputstupf,stegf2.23.06.2481getc,putctup,cteg3.43.08.4483fgetc,fputctupf,ctegf6.43.00.5251表1-3中的单字节时间8.329.7934.324对于这三个标准O/I版本的每一个,其用户UPC时间都大于表1-3中的最佳daer版本,因为每次读一个字符版本中有一个要执行051万次的循环,而在每次读一行的版本中有一个要执行30000次的循环。在daer版本中,其循环只需执行081次(对于缓存长度为2918字节)。因为系统UPC时间都相同,所以用户UPC时间的差别造成了时钟时间的差别。系统UPC时间相同的原因是因为所有这些程序对内核提出的读、写请求数相同。注意,使用标准O/I例程的一个优点是无需考虑缓存及最佳O/I长度的选择。在使用stegf时需要考虑最大行长,但是最佳O/I长度的选择要方便得多。表4-5中的最后一列是每个niam函数的文本空间字节数(由C编译产生的机器指令)。从中可见,使用cteg的版本在文本空间中作了cteg和ctup的宏代换,所以它所需使用的指令数超过了调用ctegf和ctupf函数所需指令数。观察cteg版本和ctegf版本在用户UPC时间方面的差别,可以看到在程序中作宏代换和调用两个函数在进行本测试的系统上并没有造成多大差别。使用每次一行O/I版本其速度大约是每次一个字符版本的两倍(包括用户UPC时间和时钟时间)。如果stegf和stupf函数用cteg和ctup实现(例如,见nahginreKei和hctiR〔8891〕的7.7节),那么,可以预期stegf版本的时间会与cteg版本相接近。实际上,可以预料每次一行的版本会更慢一些,因为除了现已存在的60000次函数调用外还需增加3百万次宏调用。而在本测试中所用的每次一行函数是用)3(ypccmem实现的。通常,为了提高效率,ypccmem函数用汇编语言而非C语言编写。这些时间数字的最后一个有趣之处在于:ctegf版本较表1-3EZI中SFFUB=1的版本要快得多。两者都使用了约3百万次的函数调用,而ctegf版本的速度在用户UPC时间方面,大约是后者的5倍,而在时钟时间方面则几乎是001倍。造成这种差别的原因是:使用daer的版本执行了3百万次函数调用,这也就引起3百万次系统调用。而对于ctegf版本,它也执行3百万次函数调用,但是这只引起063次系统调用。系统调用与普通的函数调用相比是很花费时间的。需要声明的是这些时间结果只在某些系统上才有效。这种时间结果依赖于很多实现的特征,而这种特征对于不同的XINU系统却可能是不同的。尽管如此,使这样一组数据,并对各种版本的差别作出解释,这有助于我们更好地了解系统。在本节及9.3节中我们学到的基本事实是:标准O/I库与直接调用daere和tirw函数相比并不慢很多。我们观察到使用cteg和ctup复制M1字节数据大约需0.3秒UPC时间。对于大多数比较复杂的应用程序,最主要的用户UPC时间是由应用本身的各种处理花费的,而不是由标准O/I例程消耗的。5.9二进制O/I5.6.5节中的函数以一次一个字符或一次一行的方式进行操作。如果为二进制O/I,那么我们更愿意一次读或写整个结构。为了使用cteg或ctup做到这一点,必须循环通过整个结构,一次第5章标准I/O库101下载读或写一个字节。因为stupf在遇到llun字节时就停止,而在结构中可能含有llun字节,所以不能使用每次一行函数实现这种要求。相类似,如果输入数据中包含有llun字节或新行符,则fgetstegf也不能正确工作。因此,提供了下列两个函数以执行二进制O/I操作。#include<stdio.h>size_tfread(void*rtp,size_tezis,size_tjbon,FILE*pf;)size_tfwrite(constvoid*rtp,size_tezis,size_tjbon,FILE*pf;)两个函数的返回:读或写的对象数这些函数有两个常见的用法:(1)读或写一个二进制数组。例如,将一个浮点数组的第2至第5个元素写至一个文件上,可以写作:floatdata〔01〕;if(fwrite(&data〔2〕,sizeof(float),4,fp)!=4)err_sys("fwriteerror");其中,指定ezis为每个数组元素的长度