PLIST 将.PBT文件的结果转换到一个格式化的文本文件中。
语法 PLIST [options] inputfilePLIST按照从左向右的顺序读取命令行,因此最右面的命令行参数有可能会覆盖左面与之相矛盾的命令行参数。所有的参数都是大小写不敏感的。不过你必须要为选项前加上(/) 或者(–)符号,并用空格将参数隔开。
缺省状态下,PLIST的结果输出到标准输出流(STDOUT)中。使用一个(>)符号可以将结果字符串重定向到一个文件或者设备。
PLIST必须在进行性能测试的程序被编译的目录下进行执行。
参数
描述
options
参考下面的可选参数。
inputfile
指定PLIST读入的.PBT文件。
Options
Option
Description
/C count
指定需要显示的最少的函数调用次数。
/D directory
为PLIS搜索源文件指定一个附加的目录。可以使用多个/D参数来指定多个目录。当PLIST找不到源文件的时候使用这个选项。
/F
在一个制表符文件中列出全路径。
/FLAT
当显示函数的属性时(参考PREP的/AT选项),显示函数属性的时候不缩进。
/H[ELP]
提供关于PLIST的参数的简单帮助信息。
/INDENT
当显示函数的属性时(参考PREP的/AT选项),格式化输出函数的属性。 如果没有使用/FLAT或者/TAB参数,这就是缺省参数。
/NOLOGO
去掉PROFILE的版本信息。
/PL length
设置页面的输出长度(行为单位)。长度必须为0或者在15到255之间。如果为0则去掉分页符号。缺省为0。
/PW width
设置输出的页宽(字符单位)。这个宽度必须在1到511之间。缺省的宽度是511。
/SC
输出按照计数排序,计数最多的在最上面。
/SL
按照行顺序对输出排序。这是对按源代码行进行性能统计时的缺省设置。
/SLS
强迫按照源代码行调用的计数进行输出的时候按照覆盖格式输出。
/SN
对输出按照函数名的字母顺序排序。这个选项只对函数的性能做测试的时候有效。
/SNS
采用函数覆盖的形式显示函数的调用时间和函数的调用次数。结果要按照字母顺序排序。
/ST
输出按时间排序,用时最多的在最上面。
/T
用制表符分割输出。从.PBT文件中生成一个用制表符分割的数据。当使用这个参数的时候,所有的其他参数被忽略。
/TAB indent
当显示函数的属性时(参考PREP的/AT选项),为缩进显示函数信息设置表宽。
/?
提供关于PLIST的参数的简单帮助信息。
环境变量
PLIST
指定缺省的命令行参数。
如果没有指定PLIST的环境变量,缺省的参数由Profile决定,如下表所示。
Profile 类型
排序选项
调用计数选项
函数计时
/ST
/C 1
函数调用计数
/SC
/C 1
函数覆盖
/SN
/C 0
行计数
/SL
/C 0
行覆盖
/SLS
/C 0
Profiler Won't Merge Statistics from Two Different Operating Systems on the Same Computer
(译者注:本节的标题是:“不要试图合并同一台计算机上的不同操作系统下的Profiler产生的性能统计结果”。Merge的意思就是执行本次性能统计的时候,数据与以前的结果数据合并,产生一个平均的统计结果。)
Profile工具不会合并在两个不同操作系统上产生的Profile会话。如果你从WindowsNT上拷贝一个Profile会话到Windows95上并试图合并结果的话,会产生如下的错误:
PREP : fatal error PRF1463: different clock/sampling frequency
不要试图合并在两个不同操作系统上得到的性能统计结果,请注意,这是Profile的设计者决定的。
错误再现 生成一个示例程序并使用工程设置对话框进行性能测试设定。(在Build菜单的Settings选项内)。 编译工程。 点击Build菜单下的Profile选项,并选中Function Timing执行。 退出,并进入一个不同的操作系统,例如,如果你刚才使用的Windows95,现在就进入WindowsNT(或者相反,从Windows NT退出并进入Windows 95)。 进入VC的IDE,点击Build菜单下的Profile选项,并选择Merge来运行Profiler。 注意事项如果是不同计算机下的相同操作系统,执行性能测试的时候是不会出错的。即使是不一致的时间统计也是可以执行合并操作的。
Profiler Will Not Profile DLLs That Are Freed, Then Reloaded
微软的源代码性能统计工具(Microsoft Source Profiler)可以对任何Windows应用程序中第一次加载的动态库(dynamic-link libraries)进行性能统计,但是它无法继续收集那些应用程序运行过程中被释放以后再次加载的动态库的性能数据(采用动态方法加载)。
采用LoadLibrary( )的方法动态加载的动态库,被释放以后再次被加载的时候,不会再次进行性能统计,因为统计的结果是不正确的。
Profile的这种行为,你可以通过执行以下的动作观察到:
使用LoadLibrary( )动态加载一个动态库。 使用FreeLibrary( )释放该动态库。 使用LoadLibrary( )再次加载该动态库。当前没有办法绕过Profile的这种局限性,在Windows下获得被动态重新加载的动态库的能力已经被考虑到下一个版本的Profiler中实现(译者注:不知道新版的VC提供了这个功能没有,有知道的请告诉我一声)。
Onboard System Memory Cache and Disk Caches May Affect Profile Times
微软的源代码性能统计工具(Microsoft Source Profiler)也许在一些特定的处理器系统上执行时,显示的应用程序执行时间会很奇怪,这些处理器包括拥有内建缓存的80386和80486处理器。要想去掉这些缓存给性能带来的影响的唯一方法就是设置这些缓存无效,因为我们无法控制哪些东西可以放到缓存中,而哪些不能放到缓存中。
这些奇怪的性能统计结果是由于缓存的行为造成的。如果正在执行性能统计的程序代码正好就放在缓存中,那么程序的执行时间会比正常情况下更短。另一方面,当Profiler本身的代码指令被放到缓存中,看起来缓存就好像被Profiler支配着一样。这导致的结果就是进行性能测试的程序本身的执行时间会增加。缓存对小程序的影响超过了大程序。这是因为缓存的命中率的原因。
由于缓存的存在妨碍了正确的执行性能测试,如果你需要得到一个很准确的性能测试结果,请使用没有缓存的系统。不管怎么样,一个带缓存的系统给性能测试带来的所有影响是让这个系统运行的更快了,因此,进行性能测试的时候,对这种额外的执行效率上的收获也没有必要考虑的太多。
Profiling Windows NT Services
这一节的主题是对Windows NT服务进程进行性能测试。
从如下目录可以找到服务例程:samples\sdk\winnt\service(当然要首先安装SDK的例程),然后按照以下步骤来得到它的服务函数的时间信息。
对Windows NT服务执行性能测试 使用系统控制面板设置必要的环境变量(译者注:Windows2000下是在系统特性的高级标签下的环境变量设置对话框)。你能找到一些系统的环境变量例如: ComSpec,windir,以及Path。 添加两新的环境变量。__ProfilePBI=<你的PBI文件的全路径>
__ProfilePBO=<你的PBO文件的全路径>
请注意不要漏掉两个环境变量前的下划线。如果没有进行正确的设置,你会得到PROFILE.DLL 给出的警告,它找不到上面的设置。在这个例子中,如果你的编译器位于驱动器D,那么环境变量的值应该设置为:
d:\...\samples\sdk\winnt\service\simple.pbi
d:\...\samples\sdk\winnt\service\simple.pbo
拷贝profiler的动态库,PROFILE.DLL, 从目录“Program Files\Microsoft Visual Studio\VC98\bin”下拷贝到或者服务的.EXE程序所在的目录,或者PATH环境变量指定的任意一个目录。 编译例程,SIMPLE.EXE。记住让编译器生成.MAP文件。 运行PREP并生成SIMPLE._XE,这是一个被修改的可执行文件,以用于性能测试(Profiling):prep /om /ft /sf _worker_thread simple.exe
这个命令同时也设置了跟踪worker_thread()的调用堆栈,缺省情况下,Profiler从主线程开始进行性能测试,如果服务请求的响应是由第二线程执行的,如果不指定/SF的参数,我们将得到不完整的结果。在这个例程中,这个第二线程是由调用CreateThread()来为请求服务的,如果主线程响应服务请求,你就没有必要使用/SF参数。 重命名SIMPLE._XE为SIMPLE.EXE。这会使用修改后的版本(针对Profiling)覆盖原来的版本,这个版本中的代码可以被Profiler钩住(Hook)。 使用控制面板下的服务管理器开始服务,并运行客户端程序,然后再停止服务,你可以使用如下的命令行指令得到执行的性能统计:prep /m simple
plist simple
Error Writing to .PDB File After Line Profile Operation
如果你在工程中执行了一次源代码行的性能统计以后,马上试图重建工程(Build或者Rebuild),你可能会得到如下的错误信息:
LNK1201: error writing to program database "c:\Microsoft Visual Studio\Common\msdev98\MyProjects\yourapp\Debug\yourapp.pdb"; check for insufficient disk space
因为这个时候开发环境在执行源代码行性能统计没有关闭工程的程序数据文件(.PDB)。这时候试图重建工程,链接器无法向.PDB中写入信息,这样就导致了LNK1201错误。
有几种办法可以解决这个问题:
退出开发环境然后再打开工程。 运行调试器,在Build菜单下选择Debug命令(快捷键F5)。然后关闭应用程序或者停止调试。这样就可以关闭.PDB文件。 使用一个补丁文件来对你的程序进行性能测试。你可以使用Profile对话框下的Custom Settings 来指定LCOVER.BAT 文件,就很容易做到了。Profiler Fatal Errors PRF1012 and PRF1306
当使用VC的集成开发环境(IDE)试图对一个程序进行性能测试的时候,你也许会得到如下的致命错误信息:
PROFILE.DLL : fatal error PRF1012 : cannot read expected number of bytes from file <path>\xxxx.pbi
PREP : fatal error PRF1306: PBT or PBO file <path>\xxxx.pbo is not derived from same PBI file
也可能是这样的错误信息:
PROFILE.DLL: fatal error PRF1005: operating system ran out of memory.
所有这些错误信息都是由于Profiler在加载动态库的过程中使用了不正确版本的PROFILE.DLL所造成的。最可能发生的情况就是Windows NT加载的PROFILE.DLL版本是Visual C++ 32-bit 版的1.0版,
要想纠正这个错误,请确认Profiler使用的PROFILE.DLL是Visual C++ 32-bit 版的2.0或者2.1版以后的版本。请在你的系统上进行一次文件搜索,看一看是否存在老版本的PROFILE.DLL,如果有请重命名或者直接删除这个文件。请确认你系统上加载的是位于Program Files\Microsoft Visual Studio\VC98\bin目录下由VC++使用的PROFILE.DLL。
如果由于什么原因,在Program Files\Microsoft Visual Studio\VC98\bin目录下不存在PROFILE.DLL文件,你可以使用VC++的安装程序进行习惯安装,这样可以恢复这个文件。
这么做的时候,先清空“Tools Options”对话框下的所有可选项,只保留“Profiler”。当然,你也要确信你指定的安装目录是你当前VC的安装目录。
不正确的PROFILE.Dll文件也许可以在winnt\SYSTEM32目录下找到,这里winnt是Windows NT的安装目录。或者这个DLL会在PATH环境变量指定的其他什么目录下找到。而正确的文件应该位于“Visual C++ Program Files\Microsoft Visual Studio\VC98\bin”目录下。
以下是直到VC 6.0以前的PROFILE.Dll文件的日期和文件大小。
Visual C++ 5.0 : 10/01/97 10:47p 107,520 PROFILE.DLL Visual C++ 4.2 : 02/08/96 07:48p 93,184 PROFILE.DLL Visual C++ 4.1 : 02/08/96 07:48p 93,184 PROFILE.DLL Visual C++ 4.0 : 09/29/95 09:49p 78,848 PROFILE.DLL(译者注:类似这个问题我本人也遇到过,这倒可能是一个司空见惯的现象。)。
本文地址:http://com.8s8s.com/it/it2179.htm