|
在决定了继续使用函数回调的机制实现 uSer和Apper之间通信的方法,在继续实现以前,我们先做一件很重要的事情。
我们来进行一次简单的 时间开销 测试。
因为使用的难易可以通过改进,但是时间开销却是一个硬性指标。
我们已经大致预见到,这样的函数回调数量不会少。(想想,i2c等时序都需要IO实现,所以这样的回调是非常多的,所以它的时间开销会产生致命性影响,不可不慎查。)
为了方便起见,我们采用一种不需要任何其他条件的方法,在debug模式下,通过比较 普通函数调用 和 通过函数指针调用函数 所用的时间差别。
因为我们只关心相对比例,所以我们不需要一个多么精确地计时器。
为此,一个最简单的实现方法是一个 定时中断。
我们也不采用复杂的uSer和Apper这种复杂的调用机制,而是最一般的做法。
以下是code:- void TestFun(void)
- {
- }
- extern U16 Times;
- void main(void)
- {
- static U16 i;
- void (*pTest)(void) = NULL;
-
- Timer_Initial();
-
- pTest = TestFun;
-
- while(1)
- {
- Times = 0;
- for(i = 0;i < 5000;i++)
- //TestFun();
- (*pTest)();
- i = 0; // for breakpoint here.
- }
复制代码- U16 Times = 0;
- #pragma vector=0xF
- __interrupt void TIM2_UPD_OVF_BRK_IRQHandler(void)
- {
- TIM2_ClearITPendingBit(TIM2_IT_UPDATE);
-
- Times++;
- }
复制代码 上面是main函数,下面是 定时中断,整个函数非常纯粹。
在debug时,把断点设在 i = 0;的语句。
测试发现,直接调用函数,断点时Timer值为17;
而通过函数指针调用,断点时Timer值为19;
这个比例说起来不算太大,但也不小。
既然已经做了测试,我们不妨再做一个更加符合真实情况的测试。判断函数指针是否为NULL
——实际应用中,不管是调用前直接判断,还是函数一开始就判断,其实说起来都是多了一句判断,所以这个测试是非常符合实际的。- while(1)
- {
- Times = 0;
- for(i = 0;i < 5000;i++)
- {
- //TestFun();
- if(pTest != NULL)
- (*pTest)();
- }
- i = 0; // for breakpoint here.
- }
复制代码 现在测试的结果是 23.
这个结果就比较危险了。
23-17/17 将近1/3.
|
|