WinCE OAL中的Profiler的实现

OAL中的Profiler的实现是指Monte Carlo Profiler,作为WinCE Kernel profiler的一种,它主要是通过高精度Timer的中断来进行周期性的计数,从而统计各函数的sample数,达到评测某一个模块或者函数的性能的目的。

 关于OAL中Monte Carlo Profiler的实现,有一篇不错的文章如下:

http://blogs.msdn.com/ce_base/archive/2006/01/23/516637.aspx

 我想我在这里要说的大概也是这个意思,可能会解释的稍微详细一点。下面介绍一下如何实现:

1. 实现OEMProfileTimerEnable和OEMProfileTimerDisable

当profiler启动的时候会调用OEMProfileTimerEnable函数来启动一个高精度的Timer,该函数还会注册并使能Timer中断。当profiler停止的时候会调用OEMProfileTimerDisable函数来停止Timer的运行,同时也会屏蔽Timer的中断。举例说明一下:

VOID OEMProfileTimerEnable(DWORD interval)

{

    BOOL enabled;

    UINT32 Irq;

 

    // Profiler已经启动,直接返回

    if (g_profiler.enabled) return;

 

    // 计算高精度Timer的count数

    g_profiler.countsPerHit = (g_oalTimer.countsPerMSec*interval)/1000;

 

    // 关闭中断

    enabled = INTERRUPTS_ENABLE(FALSE);

    // 赋值Profiler的中断处理函数

    g_pProfilerISR = OALProfileIntrHandler;

    // 配置高精度Timer的count值

    ConfigureNextProfilerCount(g_profiler.countsPerHit);

    // 打开中断

    INTERRUPTS_ENABLE(enabled);

    Irq = IRQ_TIMER2;

    OALIntrDoneIrqs(1, &Irq);

 

    // 设置Profiler使能标记位

    g_profiler.enabled = TRUE;

}

 

VOID OEMProfileTimerDisable()

{

    BOOL enabled;

    UINT32 irq;

 

    // Profiler已经屏蔽,直接返回

    if (!g_profiler.enabled) return;

 

    // 关闭中断

    enabled = INTERRUPTS_ENABLE(FALSE);

 

    // 清楚高精度Timer的中断标记位   

    g_pPWMReg->TINT_CSTAT = TINT_CSTAT_INTMASK(g_pPWMReg->TINT_CSTAT) | TIMER2_PENDING_CLEAR;

    // 禁用高精度Timer

    g_pPWMReg->TINT_CSTAT = TINT_CSTAT_INTMASK(g_pPWMReg->TINT_CSTAT) & ~TIMER2_INTERRUPT_ENABLE;

    // 屏蔽高精度Timer中断

    irq = IRQ_TIMER2;

    OALIntrDisableIrqs(1, &irq);

 

    // 设置Profiler的中断处理函数为NULL

    g_pProfilerISR = NULL;

 

    // 设置Profiler标记位

    g_profiler.enabled = FALSE;

 

    // 打开中断

    INTERRUPTS_ENABLE(enabled);

}

 

2. 实现OALProfileIntrHandler来处理Profiler的中断

 函数OALProfileIntrHandler用于处理高精度Timer的中断,该函数会在OEMInterruptHandler中被调用,并返回SYSINTR_NOP。在该函数中需要调用ProfileHit函数,这里传入ProfileHit函数的参数要和OEMInterruptHandler的参数一致。举例如下:

UINT32 OALProfileIntrHandler(UINT32 ra)

{

    UINT32 Irq;

 

    // 更新高精度Timer的计数

    ConfigureNextProfilerCount(g_profiler.countsPerHit);

 

    // 调用ProfilerHit采样

    ProfilerHit(ra);

 

    // 使能Timer

    Irq = IRQ_TIMER2;

    OALIntrDoneIrqs(1, &Irq);

 

    return(SYSINTR_NOP);

}

 

在OAL中实现上面的3个函数就可以了,要支持Monte Carlo Profiler还需要对你的WinCE工程做其它的设置。在WinCE的编译选项中选择”Enable profiling (IMGPROFILER=1)”并确认config.bib文件有如下代码:

IF IMGPROFILER

    PROFILE=ON

ELSE

    PROFILE=OFF

ENDIF

 

最后要做的就是Makeimg了。在WinCE运行以后,可以通过以下几种方法控制Monte Carlo Profiler,如下:

1. 通过Target Control命令来控制

 prof on -m 启动Monte Carlo Profiler

prof off 停止Profiler

 

2. 通过键盘来控制

如果系统支持键盘,那么默认情况下,键盘是支持Profiler的控制的。按F9启动Monte Carlo Profiler,按F12停止Profiler功能。实际上,在按下这些按键的时候系统调用了API函数来启动和停止Profiler,分别是ProfileStart和ProfileStop函数。

 

3. 通过Profiler的API函数来到控制

通过ProfileStart和ProfileStop函数来控制。

 

VOID ProfileStart(DWORD dwUSecInterval, DWORD dwOptions)

dwUSecInterval:采样精度,微秒级。

dwOptions:Profiler的标记位

    PROFILE_BUFFER:使用Buffer模式

    PROFILE_CONTINUE:恢复Profiler采样

    PROFILE_KCALL:记录内核调用

    PROFILE_OBJCALL:记录目标调用

    PROFILE_PAUSE:停止Profiler采样

    PROFILE_STARTPAUSED:启动Profiler但处在暂停状态

该函数用于启动Profiler,一般在Buffer模式下,推荐将dwUSecInterval设置为200微秒。

 

VOID ProfileStop (void);

该函数用于停止Profiler功能。

 

转自:http://blog.csdn.net/nanjianhui/archive/2009/04/15/4076593.aspx

posted @ 2010-08-25 14:49  温子祺  阅读(310)  评论(0编辑  收藏  举报