AQtime学习资料

更新时间:2024-05-25 06:51:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

AQtime的简介

参考文献:AutomatedAQ's AQtime

一、AQTIME的功能:

AQTIME含有完整的性能和调试工具集,能够收集程序运行时关键的性能信息和内存/资源分配信息,并提交概要报告和详细报告,还提供所有的程序优化处理工具,囊括了自定义过滤器、图形化的调用层次结构一直到源代码浏览等内容。AQTIME的特色在于它不仅是一款调试工具,还是一款性能优化工具。另外,还支持与基于SCC API的版本控制软件集成使用。

二、AQTIME的界面:

对以上界面中的相关面板的功能进行描述:

1.主面板:

1).Setup:

此面板配置需要收集信息的程序。 2).Event View:

此面板用来显示收集待测程序的过程中,它所发生消息和事件信息。 3).Report:

结果报告。值得注意的一点是:如果待测程序使用的是多线程方式,那么在此面板的Thread下拉菜单中可以选择单一线程或者所有线程,另外对结果信息可以进行过滤。 4).Explorer:

树形结构,方便对结果的管理和浏览。

2.结果面板:

1).Details:

此面板用来显示Report Panel中选中的某一行结果的附加(细节)信息。 2).Call Graph:

以图形的方式显示函数调用关系以及调用次数。 3).Call Tree:

以树形的方式显示函数调用关系。 4).Editor:

源代码显示框。如果待测程序有源代码支持的话,可以配置相应工程路径并在此窗口显示,可以用于性能测试和代码覆盖率测试。 5).Summary:

摘要信息。测试结果的摘要统计信息,通过此面板可以找到可以优化的routines 和 classes。 6).Disassembler:

反汇编代码的显示。

3.AQTime的右侧面板:

1).Assistant:

AQTIME的帮助信息,以上的所有资料就是通过它查到的。 2).PE Reader:

PE Reader面板提供AQTIME主模块的执行信息。通过它可以很容易地看到在程序装入时有哪些模块被链接到,从而判断出哪些模块对应用程序的功能实现是有用的。 3).Monitor:

监控面板,实时地监控已分配的内存的大小、已存在的对象句柄信息等。此面板在Allocation Profiler中使用。

三、AQTIME的使用步骤:(一般情况下)

1.Compiling your application with debug information. 2.Opening your application in AQtime.

3.Controlling what to profile and when to profile. 4.Selecting the profiler to run.

5.Running the selected profiler and analyzing the results.

四:AQTIME Profilers:

1.Allocation(资源测试):

测试资源分配释放情况,检查内存泄漏。 ? 资源测试

?

内存测试

2.Coverage(代码覆盖率测试):

测试出代码在运行过程中的执行情况。它提供routine 和 line两种级别,可以帮助查找出程序中的无用代码。有时手工调试时,可能只调试了部分代码,有些代码没有运行到。这部分没有运行到的代码,很可能会产生问题。可通过软件运行,保证所写代码达到98%以上都运行过,并没有产生问题。

3.Performance(性能测试):

在程序执行期间,工具自动收集运行时的性能表征数据(如调用次数、执行时间、调用与被调用函数、函数调用层次图、执行期间发生的异常情况等等)。此外,工具提供与运行时间、CPU缓存使用等相关的多种计数器[如Elapsed Time、User Time、User+Kernel Time、CPU Cache Misses、

Context Switches等],为了解应用代码级和应用程序级上的性能使用和确定可能存在的性能瓶颈提供详实的参考数据。

4.Static Analysis(静态分析) :

?

Platform ComplianceAPI(API平台支持测试),程序中使用的API函数与特定平台的兼容性分析,识别出与操作系统不兼容的函数。这样不用手工在不同操作系统上安装软件,就能正确分析出,软件可以在什么样操作系统上运行。

Sequence Diagram Link(UML关系图)自动识别出待测程序中的函数调用关系,自动生成UML格式时序图,并通过word或visio格式显示。

Static Analysis(静态分析),静态分析并标识出待测程序的内部结构[如UML时序图、函数间调用关系、存在的循环语句、判断语句、异常处理]和程序规模[Bytes、lines]。

? ?

5.Exception Tracer(异常跟踪):

监测程序运行期间出现的预知和未知异常,并将异常在源代码中进行定位。当程序出现异常时,Event Log窗口会记录下来,再Event View窗口选中异常查看,在Editor窗口中可以查看到当前异常所在的代码位置。这样可以减少手工跟踪的时间。

五、AQtime的初次尝试:

源代码:LuboView

开发环境:Visual Studio C++ 2005

1.设置Microsoft Visual C++ 2005的编译模式:

AQTime的帮助文档中提到: 默认情况下,Microsoft Visual C++ 2005的编译模式已经设置为Debug,并且在DEBUG中已经包含了有价值的信息,但是因为我们所测试的程序是最终的发布版本Release,所以强烈建议将the active configuration改为Release ,当然前提是做性能测试。 设置方法:

1).在Visual Studio 2005中打开工程。

2).在主菜单下,选择Build | Configuration Manager ,在弹出的窗口Configuration Manager对话框中,选择Release Configurations。

关闭对话框。

3).在Solution Explorer 上单击右键并选择Properties。

4).切换至Configuration Properties | C/C++ | General页面,将Debug Information Format 对应的内容选成Program Database 或者 Program Database for Edit & Continue 。

5).打开Configuration Properties | Linker | Debugging属性页面,将Generate Debug Info选项设为Yes(/DEBUG)。

6).点击OK保存配置,并且重新构建程序。

用AQTime打开待测程序之前,确保工程文件的output目录下存在.pdb文件。另外,此目录下需包含vcX0.pdb文件,其中X代表Visual C++的版本,比如:Visual C++ 8.0对应的文件名为VC80.pdb。vcX0.pdb文件中包含部分DEBUG信息,这对于AQTime的结果正确性是有帮助的。如果vcX0.pdb文件不是由Visual Studio产生的,那么很有可能造成Profiling时出现问题。如果测试的是Active X控件或者是COM Server的话,需要在系统中注册它的DEBUG版本。

2.Resource Profiler测试

1).新建项目File->New Project. 2).在Setup添加LuboView.exe。

3).选择Profiler为Resource Profiler。

4).点击Run按钮,在弹出的对话框中点击Run。 5).在Event View中可以查看到以下信息: Even t Product: AQtime; Version: 4.92.669.0 Work environment: Thread ID Time - Project run selected, current profiler is Resource Profiler. 15:18:30:843 - Host name: SOHU-ZGDM OS: Microsoft

Windows XP Service Pack 2 5.1 Build 2600 Windows directory: C:\\WINDOWS; System directory: C:\\WINDOWS\\SYSTEM32 Current user: Administrator Number of processors: 2 Processor: Intel(R) Pentium(R) D CPU 3.00GHz, Frequency: ~2992 MHz. Memory in use: 42% Total Physical Memory: 2,145,427,456 bytes; Available Physical Memory: 1,238,437,888 bytes; Total Virtual Memory: 2,147,352,576 bytes; Available Virtual Memory: 1,806,143,488 bytes; Virtual Memory In Use: 341,209,088 bytes Microsoft .NET Framework version: v2.0.50727 - Process create ID: 5592, Thread ID: 4216, Base address: 0x00400000 Run Mode: Normal Host Application: Parameters: Work Directory: 4216 15:18:31:000 Module loaded: D:\\Test\\LuboView\\Debug\\LuboView.exe; Base address: 0x00400000 Size: 3039232 Version: 1.0.0.1 ?????.. 4216 15:18:31:000 从以上事件信息中可以看到AQTIME在RUN之后,首先会获取如下一些信息: a).当前AQTIME的版本信息:

Product:Aqtime;Version:4.92.669.0 b).系统工作环境:

Host name:SOHU-ZGDM

OS:Microsoft Windows XP Service Pack 2 5.1 Build 2600 Windows directory: C:\\Windows

System directory:C:\\Windows\\SYSTEM32 Current user:Administrator Number of Processor:2

Processor:Inter? Pentinum? CPU 3.00GHz,Frequency:~2992MHz. Memory in use:42% Total Physical Memory:2,145,427,456 bytes; Available Physical Memory:1,238,437,888 bytes; Total Virtual Memory:2,147,352,576 bytes; Available Virtual Memory:1,806,143,488 bytes; Virtual Memory in Use: 341,209,088 bytes =2GB =1.15GB =2GB =1.68GB =325.4MB Microsoft.NET Framework version:v2.0.50727 c).运行参数。

因为没有在RUN->parameters下设置相关内容,所以此处为空。但这里有何作用还有待于将来继续实践。

d).创建进程,进程ID号为5592,线程ID号为4216,基址为0x00400000 e).加载程序:

D:\\Test\\LuboView\\Debug\\LuboView.exe; 基址:0x00400000 大小:3039232 版本:1.0.0.1 f).加载动态链接库:

C:\\Windows\\system32\\ntdll.dll 基址:0x7C920000 大小:591360

版本:5.1.2600.2180

??..加载其他动态链接库,如kernel32.dll,user32.dll,gdi32.dll

6).Monitor面板提示:

当前的profiler不支持Monitor面板;Disassembler面板和Editor面板中会显示汇编代码和VC源代码,前提配置了源代码文件的搜索路径。Details面板,Call Graph面板,Call Tree面板 没有内容。 7).LuboView软件加载曲线。

8).结束LuboView进程,查看AQtime的统计结果:

a).资源文件报告:点击侧边栏Last Results中Classes项

从以上分析结果可以看出,一共建立了图标类67个,而有57个没有释放;注册表类创建了376个,有29个没有释放;DC设备类有400个创建,14个没有释放;位图BitMap创建了236个,9个没有释放;PEN类创建了181个,全部释放?等等。并且在侧边栏的Last Results中有Errors相关的报告,报告内容主要是句柄无效。这可能与之前杀LuboView进程所造成的资源没有释放有关。

b).点击侧边栏中Objects项,如图:

从上可以看出,Report栏里是具体每个资源文件的信息,并且在下边的Details中可以看到函数调用的顺序。 c).切换到Summary显示方式:

从上图可以看到AQtime为程序测试结果总结了摘要信息: 共发生了375次错误,有138处资源文件的内存泄漏。

3.Performance Profiler测试

1).用Visual Studio 2005编写一个测试程序:

#include \

void ShowHello(); void ShowBye();

int _tmain(int argc, _TCHAR* argv[]) {

printf( \

for ( int i = 0 ; i < 1000; i++ ) {

ShowHello(); }

ShowBye();

return 0; }

void ShowHello() {

printf( \}

void ShowBye() {

printf( \}

2).设置编译版本为Release,编译程序。

3).打开AQtime,创建工程并加载编译好的Win32_Perfor_Test.exe程序.(如果Relase目录下的*.pdb不存在的话,无法进行测试。如果Relase目录不在源代码目录下,可能需要在Editor中设置路径。)

4).设置测试范围:在Areas下添加测试域“main”,并且设置测试级别为Line。 5).设置Profile的起始时间:在Trigger中添加当执行到Main函数时启动Profiler。

测试结果截图:

从截图中可以看到,ShowHello执行了1000次,所花费的时间为70867.67微秒,平均每次执行时间为70.87微秒。

Compiling your application with debug information

In order to profile your application with AQtime you may need to compile it with debug information.

一、Native-code(unmanaged) applications:

用以下工具编写的程序必须编译时加入debug信息: ? Microsoft Visual C++ ? ? ? ? ? ? ? ? ? ? ?

- Native code is computer programming (code) that is compiled to run with a particular processor (such as an Intel x86-class processor) and its set of instructions. If the same program is run on a computer with a different processor, software can be provided so that the computer emulates the original processor. In this case, the original program runs in \in native mode on the original processor. (The program can be rewritten and recompiled so that it runs on the new processor in native mode.)

源文档

Microsoft Visual Basic

CodeGear Delphi 2007 for Win32 Borland Delphi 2006 for Win32 Borland Delphi 2005 for Win32 Borland Delphi Borland C++Builder 2006 Borland C++Builder Borland C++ Intel C++

GCC (GNU Compiler Collection for Windows) Compaq Visual Fortran

二、Managed(.NET) applications(托管应用程序):

一般情况下,用.NET开发的应用程序通过metadata(元数据)已经为Profiling提供了一些必要的信息;但是metadata中没有提供源代码与应用程序内部细节的链接信息,所以AQtime的有些功能无法使用,比如Editor面板将不会显示具体的源代码等等;为了能够得到消除这种局限性,也需要在开发工具做一些相关的设置,将Debug信息加入到已经存在的.NET元数据中。 AQtime支持的.NET开发工具:

? ASP.NET

? ? ? ?

Microsoft Visual C# 2005 Microsoft Visual C# .NET Microsoft Visual J# 2005 Microsoft Visual J# .NET

? ? ? ? ? ? ? ? ?

Microsoft Visual Basic 2005 Microsoft Visual Basic .NET Microsoft Visual C++ 2005 Microsoft Visual C++ .NET Borland C#Builder 2006 Borland C#Builder Borland Delphi 2006 for .NET Borland Delphi 2005 for .NET Borland Delphi 8 (Delphi for .NET)

三、Visual C++ 6.0和Visual C++ 2005的设置方法:

1.Visual C++ 6.0:

1. Open your project in Visual Studio.

2. Choose Build | Set Active Configuration from Visual C++'s menu and select another

configuration, say Debug, as the active configuration for the project.. Usually the Debug configuration is similar to this: - Win32 Debug:

Note that the only reason to change the active configuration is to leave the Release

configuration unaffected. If you want to profile the Release configuration, you may skip this step. In this case, do not forget to restore the compiler settings before compiling the release version of your application.

3. Now, open the Project Settings dialog (press ALT-F7 or use Project | Settings) and

select the configuration you have set.

4. In the dialog, open the C/C++ page and make sure that Debug Info is set either to

Program Database or Program Database for Edit and Continue

For more information on these options review Microsoft Visual C++ Help.

5. You now have set your project to generate debug information when compiling. Next, you

must ensure that the linker saves it. From Project | Settings select the Link page. There, first set the Category to General. Then check Generate debug info:

On the Link page, select Debug in the Category box and then do the following: ? Select the Debug info check box.

? ?

Clear the Separate type check box. Select the Microsoft format option button.

6. The last step is to set how the linker will save the debug information. AQtime supports

? Switch to the Link page of the Project Settings dialog: ? Set the Category to Customize. ? Check Use program database.

? Enter the PDB file name you want into the Program database name edit field.

debug information generated as an external PDB file (PDB format). To set linker options:

2.Visual C++ 2005:

1. Open your project in Visual Studio 2005 or Visual Studio 2008.

2. Select Build | Configuration Manager from the main menu. This will open the

Configuration Manager dialog. Select the Release configuration for your project:

Close the dialog. Note:

Of course, you can profile your application in any configuration, not just in the Release one. We recommend that you choose this configuration if you are going to use the Performance profiler (see above).

3. Right-click the project in the Solution Explorer and select Properties from the

context menu. This will call the Property Pages dialog. 4. In the dialog,

a. Select Active (Release) from the Configuration dropdown list. b. Switch to the Configuration Properties | C/C++ | General page and

set Debug Information Format to Program Database (/Zi) or Program Database for Edit & Continue (/ZI). For more information on these options review the Visual Studio documentation.

c. Open the Configuration Properties | Linker | Debugging property

page and set the Generate Debug Info option to Yes (/DEBUG).

5. Click OK to save the settings and then rebuild the application. Once finished,

your application will be ready for profiling in AQtime.

四、Release版与Debug的区别:

Debug通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。Release称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。

Debug 和 Release 的真正秘密,在于一组编译选项。下面列出了分别针对二者的选项(当然除此之外还有其他一些,如/Fd /Fo,但区别并不重要,通常他们也不会引起 Release 版错误,在此不讨论)

1.Debug 版本

参数 含义 : ? ? ? ? ? ?

/MDd /MLd 或 /MTd 使用 Debug runtime library (调试版本的运行时刻函数库) /Od 关闭优化开关

/D \相当于 #define _DEBUG,打开编译调试代码开关 (主要针对assert函数)

/ZI 创建 Edit and continue(编辑继续)数据库,这样在调试过程中如果修改了源代码不需重新编译

/GZ 可以帮助捕获内存错误

/Gm 打开最小化重链接开关, 减少链接时间

2.Release 版本

参数 含义 : ?

/MD /ML 或 /MT 使用发布版本的运行时刻函数库

? ? ? /O1 或 /O2 优化开关,使程序最小或最快

/D \关闭条件编译调试代码开关 (即不编译assert函数) /GF 合并重复的字符串, 并将字符串常量放到只读内存, 防止被修改

实际上,Debug 和 Release 并没有本质的界限,他们只是一组编译选项的集合,编译器只是按照预定的选项行动。事实上,我们甚至可以修改这些选项,从而得到优化过的调试版本或是带跟踪语句的发布版本。

3.Debug和Release对AQtime的直接影响:

测试部分代码: ……..

void PrintMessage( CString strMessage ) {

AfxMessageBox( strMessage ); }

void CDebugSettingDlg::OnBnClickedButton1() {

CString strTemp;

strTemp = \PrintMessage( strTemp );

// TODO: Add your control notification handler code here }

void CDebugSettingDlg::OnBnClickedButton2() {

CString strTemp;

strTemp = \PrintMessage( strTemp );

// TODO: Add your control notification handler code here }

1)在AQtime中添加release版待测程序:

2)在AQtime中添加debug版待测程序:

PrintMessage不是DebugSettingDlg类的成员函数,只是被OnbnClickedButton1和

OnbnClickedButton1所调用。在release模式下,PrintMessage是看不到的;但在debug模式下,PrintMessage不但可以看到,而且还可以记录其执行信息。 NOTE:

如果在编译Release模式时,将Optimization改为其他模式而非Maximize Speed,那么PrintMessage就可以看到了。

1).Disabled:

2).Minimize Size(最小体积):

3).Maximize Speed(最高速度):

4).Full Optimization(完全最优化):

Opening your application in AQtime.

一、创建工程:

在AQTIME的主菜单中选择File | New Project。

二、加入应用程序或模块:

在Setup面板的Modules窗口中右键,选择Add Module,或者点击工具条按钮,在弹出的对话框中选择待测程序或模块。

三、设置主程序:

选择主程序,右键选择Set as Active Module,设置为主程序。如图:

Controlling what to profile and when to profile

一、What to Profile —— Areas功能

1.Areas功能的意义:

当程序非常庞大而复杂时,如果将所有代码调用的信息都做Profiling的话,很难定位问题。通过Areas面板设定我们只关心的模块或代码的信息,有助于帮助我们过滤不需要的信息,最终生成有价值的报告。

NOTE: Areas只对Performance, Converage, Allocation和Function Trace起作用。

2.Area的设置:

1).自定义区域:

自定义的区域的类型有两种,一种是Including,即Profiling该区域的信息;Excluding对应的是不记录该区域的信息。Area的级别也同样分为Class,Routine和Line级别。Level级别对应也有Class,Routine和line。这三种级别的区别将在后面介绍。

2).Full Check:当此选项选中时,Profile的是整个工程的所有模块。

3).Profile Entire .NET Code:此选项与Full Check类似,所不同的是在Profiling时不但会记录当前工程中的模块,而且也会记录这些模块所使用的.NET代码。

NOTE:Profile Entire .NET Code setting only affects the managed code。 3.Profiling Levels:

1).Routine Level(模块级):

AQtime将会收集整个模块的信息,比如在性能测试中,某一个模块被调用了多少次、工作了多长时间。 2).Line Level(代码级):

AQtime将会收集每行代码的信息,比如在性能测试中,每行代码的执行时间、该代码被执行的次数等等。

NOTE:Line profiling requires information about lines in source code. 3).Class Level(类级别):

AQtime将会记录Areas中划定的类所对应对象的创建和销毁。此级别只在Allocation Profiler中启用。

二、When to Profile —— Triggers and Actions功能

1.Using Actions:

1).精确地记录时间:

场景:在测试浏览器启动性能中,假定我们规定的启动时间为:程序加载开始到界面的完全显示。那么如何记录这段时间?用秒表显然不是好办法。 解决方法:使用Actions功能的GetResults. 举例说明:

a).用VC6.0创建一个基于MFC的Dialog对话框程序。 b).在AQtime中加载此程序。

c).在Triggers and Actions中Add Action,如图:

d).将CProfilerTestDlg类中的OnInitDialog函数拖入刚才创建的Actions中:

Initial Profiling Status for Threads选项表示是否在程序创建线程时就开始Profiling。

以上的设置实现了在程序创建线程时就开始记录时间,直到OnInitDialog函数执行完毕退出后停止记录,并且生成报告。这段时间就是我们之前定义的启动时间。

e).F5运行,得到如下结果:

结果分析:从WinMain函数入口执行开始到对话框OnInitDialog完毕,共耗时61.10毫秒。其中有57.60毫秒是花费在InitInstance初始化工作中。 2).过滤无用的时间

场景:只记录程序某个功能执行的时间,需要过滤掉初始化等不关心的时间。 解决方法:综合使用Actions中的Enable Profiling和Get Results。 举例说明:

a).用VC6.0创建一个基于MFC的Dialog对话框程序如下:

b).在AQtime中加载此程序。

c). 设置开始计时的Action和结束计时的Action:

d).F5运行:

a)当不点击Start按钮时,AQtime没有记录任何数据; b)依次点击start按钮和stop按钮后,得到如下结果:

2.Using Triggers:

Triggers并不是触发器,它的使用方法与Areas类似,都是用来控制程序的哪一部分需要Profiling。所不同的是:

Areas控制的是哪一部分代码需要Profiling;而Triggers控制哪一部分执行路径需要Profiling. 举例说明:

部分测试代码:

void CProfilerTestDlg::OnButStart() {

// TODO: Add your control notification handler code here

GetDlgItem(IDC_STATE)->SetWindowText(\当前状态:运行中...\SetTimer( 1 , 100 , NULL); }

void CProfilerTestDlg::OnButStop() {

// TODO: Add your control notification handler code here

GetDlgItem(IDC_STATE)->SetWindowText(\当前状态:停止\KillTimer( 1 ); }

void CProfilerTestDlg::OnTimer(UINT nIDEvent) {

// TODO: Add your message handler code here and/or call default if ( nIDEvent == 1 ) {

m_lSum += 1; }

CDialog::OnTimer(nIDEvent); }

1).使用Areas:

在Areas中定义区域Button,并将CProfilerTestDlg::OnButStart函数加入区域下,去除Full Check by Lines复选框;:

运行程序,并点击Start按钮,得到结果:

2).使用Trigger:

勾选Full Check by LInes,并添加Trigger如图:

同样运行程序,并点击start按钮,得到结果:

对比以上两个结果图,可以发现Areas只记录了OnButStart函数的执行情况;而Trigger不但记录了OnButStart而且记录了其子函数的调用情况。

3)off-trigger的用法:

当建立一个Trigger并设置为OFF状态时,所属这个Trigger的函数或模块将不被记录,并且其子函数的调用也不会被记录。举例:

Proc_B is an off-trigger routine, profiling is currently enabled and either Full Check by Routines, or Full Check by Linesis used:

Proc_A;

Proc_B // off-trigger routine

Proc_D; // Proc_D and Proc_E are child routines of Proc_B, Proc_E; // that is, they are called within Proc_B.

// Proc_D and Proc_E are not profiled. Proc_C;

3.Setting Up Triggers

Triggers的高级选项中的配置说明: 1)Pass Count:

该选项允许某一函数或模块在被调用N次后再进行Profiling.(N默认为0,即第一次调用就开始Profiling).比如在上面的ProfilerTest程序中,如果设置Pass Count为3,那么意味着当点击start按钮第四次时,Profiling才真正开始.通过此选项可以跳过初始化的一些操作后再进行Profiling. 2)Work Count:

该选项用来设置Trigger起作用的次数。通过该选项可以限制一些我们已经知道的函数调用信息。 3)Cycling:

是否执行Pass Count->Work Count的循环执行,默认情况下不选中。此功能可以用在函数被周期性调用的情况下。举例说明:

按照以上设置后: 当点击Start按钮第2当点击Start按钮第5当点击Start按钮第6当点击Start按钮第8

次时,此时没有Profiling;

次时,Profiling记录到OnButStart函数被调用了3次; 次时,仍然只记录了OnButStart函数被调用3次; 次时,Profiling记录到OnButStart函数被调用了4次;

4)For All Threads:

影响调用Count计数的两种方式:所有线程和Trigger所在的线程。For All Threads选中的状态下,所有线程对函数调用的计数都会产生影响。

Remember that, whether or not calls are counted over all threads, triggers only act on their own thread. 多线程举例说明: #include #include #include

int CalSum( int iCount ) {

int sum=0;

for(int i=1; i <= iCount; i++)

sum=sum+i; return sum; }

DWORD WINAPI funA(LPVOID lp) {

int iResult;

iResult = CalSum( 100 );

printf(\

return 0; }

DWORD WINAPI funB(LPVOID lp) {

int iResult;

iResult = CalSum( 101 );

printf(\

return 0; }

void main() {

HANDLE a[2];

DWORD dwT,dwY;

a[0]=CreateThread(NULL,0,funA,0,0,&dwT); a[1]=CreateThread(NULL,0,funB,0,0,&dwY);

WaitForMultipleObjects(2,a,TRUE,50000);

CloseHandle(a[0]); CloseHandle(a[1]); }

a).勾选For All Threads的情况:

按照上图所设置的Trigger,CalSum函数只要被任何线程调用过一次后就不再Profiling了。结果如图:

b).不勾选For All Threads的情况:

4.By lines 和 By Routine的试验

在Area中可以设置两种测试级别:by lines 和 by routine。此选项只对Performance 和 Coverage有效。 测试程序:

#include \

class animal {

public:

virtual void shout() { printf( \};

class dog :public animal {

public:

virtual void shout() { printf( \\\n\};

class cat :public animal {

public:

virtual void shout() { printf( \};

int _tmain(int argc, _TCHAR* argv[]) {

dog onedog; cat onecat;

onecat.shout(); onedog.shout();

return 0; }

1). Performance性能测试:测试程序编译为release版时两者的测试结果

a).By routines:

b).By lines:

2). Performance性能测试:测试程序编译为debug版时两者的测试结果

a).By routines:

b).By lines:

从上可以看到by lines和by routines在性能测试中是一样的。

3). Coverage代码覆盖率测试: a).by lines:

b).by routines:

可以看到在代码覆盖率测试中,by routines是没有意义的。

c). by lines在debug和release下的区别: debug:

release:

相比较两个结果:当待测程序是debug模式时,animal::shout()函数虽然没有被调用过,但是AQtime仍然会统计其覆盖率;当待测程序是release模式时,AQTIME只统计了main函数中的代码覆盖率。

5.Trigger的复合使用及Trigger与Area的区别

测试代码如下:

#include \

class animal {

public:

virtual void shout() { printf( \};

class dog :public animal {

public:

virtual void shout() { printf( \\\n\};

class cat :public animal {

public:

virtual void shout() { printf( \};

int _tmain(int argc, _TCHAR* argv[]) {

dog onedog; cat onecat;

return 0; }

1).只使用on-trigger的情况:

测试结果中显示:

执行dog构造函数时,其父类的构造函数animal也会被记录;执行cat构造函数时,其父类的构造函数animal同样被记录。

本文来源:https://www.bwwdw.com/article/7ab7.html

Top