(转)为提高实时性能,设计和优化 Microsoft Windows CE .NET(下)
性能测量
对 Windows CE .NET 的性能测量数据是在三种不同的 x86 CPU 上采集的。所有测量数据均以微秒为单位,其结果会因为不同的系统负载而有所变化。
ILTiming 测试结果
下表显示了 ISR 和 IST 滞后时间。
注 这些数字(以微秒为单位)只应当用作具体硬件的性能示例。很多硬件和软件可变因素可能影响这些数字,所以用户应当在他们自己的平台上运行这些测试,但不一定获得相同结果。
表 1.
| 最小 | 最大 | 平均 | 最小 | 最大 | 平均 | AMD K6-2 - 350 MHz | 1.6 | 3.3 | 1.6 | 9.2 | 34.3 | 21.2 | Pentium – 166 MHz | 3.3 | 6.7 | 4.2 | 19.2 | 105.6 | 62.1 | Pentium PIII –500 MHz | 3.3 | 6.7 | 3.4 | 10 | 26.8 | 17.2 |
OSBench 测试结果
OSBench 测试运行在所有三种 CPU 上,并且使用了以下两种基本变化形式来计算性能数字:
• | 测试在相同进程中或在两个或更多个进程之间执行。 | • | 在没有缓存刷新和有缓存刷新(CacheSync)的情况下执行测试,以便刷新数据和指令缓存。 |
下表显示了 OSBench 测试的结果。结果时间以微秒为单位,以便执行具体的测试,该测试由第一列的数字表示,并定义在表后面的章节中。
注 这些数字(以微秒为单位)只应当用作具体设备的性能示例。很多硬件和软件可变因素可能影响这些数字,所以您应当在它们自己的平台上运行这些测试,但不一定获得相同结果。
表 2.
| 最小 | 最大 | 平均 | 最小 | 最大 | 平均 | 最小 | 最大 | 平均 | 1 | 9.219 | 12.571 | 9.836 | 26.819 | 32.686 | 27.776 | 6.705 | 17.6 | 7.61 | 2 | 10.057 | 12.571 | 11.14 | 28.496 | 31.848 | 29.901 | 8.381 | 11.734 | 9.71 | 3 | 0.082 | 0.088 | 0.082 | 0.144 | 0.152 | 0.145 | 0.22 | 0.229 | 0.221 | 4 | 0.067 | 0.074 | 0.067 | 0.143 | 0.155 | 0.143 | 0.221 | 0.23 | 0.221 | 5 | 9.219 | 10.057 | 9.972 | 27.658 | 30.172 | 28.631 | 6.705 | 17.6 | 7.839 | 6 | 9.219 | 12.571 | 11.258 | 27.658 | 45.258 | 31.162 | 8.381 | 11.734 | 9.659 | 7 | 6.705 | 15.086 | 7.339 | 20.115 | 25.143 | 21.486 | 5.029 | 7.543 | 5.604 | 8 | 20.114 | 24.305 | 20.977 | 67.886 | 74.591 | 69.629 | 11.734 | 22.629 | 12.825 | 9 | 6.705 | 14.248 | 7.322 | 20.953 | 30.172 | 21.664 | 5.029 | 6.705 | 5.367 | 10 | 20.114 | 20.952 | 20.427 | 68.724 | 74.591 | 69.765 | 11.734 | 20.953 | 12.775 | 11 | 6.705 | 10.895 | 7.238 | 21.791 | 27.658 | 22.925 | 5.029 | 8.381 | 6.197 | 12 | 20.114 | 25.981 | 20.325 | 67.048 | 83.81 | 70.18 | 12.572 | 21.791 | 13.164 | 13 | 6.705 | 7.543 | 7.187 | 22.629 | 29.334 | 23.966 | 5.867 | 15.924 | 6.247 | 14 | 20.114 | 23.467 | 20.503 | 69.562 | 76.267 | 70.823 | 12.572 | 16.762 | 13.604 | 15 | 8.381 | 10.895 | 8.533 | 25.981 | 31.848 | 27.166 | 6.705 | 16.762 | 7.576 | 16 | 21.79 | 25.143 | 22.298 | 72.077 | 79.62 | 74.938 | 13.41 | 15.924 | 14.569 | 17 | 8.381 | 11.733 | 8.474 | 26.819 | 41.067 | 27.708 | 6.705 | 17.6 | 7.644 | 18 | 21.79 | 25.143 | 22.154 | 72.077 | 85.486 | 76.013 | 14.248 | 23.467 | 14.798 | 19 | 3.352 | 4.19 | 3.851 | 12.572 | 21.791 | 13.384 | 2.515 | 4.191 | 3.446 | 20 | 15.924 | 21.79 | 16.499 | 52.8 | 62.858 | 53.935 | 9.219 | 19.277 | 10.023 | 21 | 3.352 | 7.543 | 4.046 | 11.734 | 16.762 | 12.817 | 2.515 | 5.867 | 3.353 | 22 | 15.924 | 19.276 | 16.635 | 52.8 | 62.02 | 53.926 | 9.219 | 20.115 | 10.057 | 23 | 2.717 | 2.74 | 2.726 | 5.385 | 5.466 | 5.42 | 2.417 | 2.514 | 2.476 | 24 | 2.647 | 2.667 | 2.653 | 5.369 | 5.405 | 5.373 | 2.386 | 2.495 | 2.463 | 25 | 2.83 | 2.839 | 2.832 | 5.932 | 5.959 | 5.935 | 2.618 | 2.728 | 2.691 | 26 | 16.623 | 16.656 | 16.641 | 46.761 | 46.785 | 46.766 | 9.386 | 9.451 | 9.412 | 27 | 16.624 | 16.672 | 16.65 | 48.881 | 48.897 | 48.886 | 9.41 | 9.517 | 9.462 | 28 | 17.302 | 17.34 | 17.322 | 47.307 | 47.323 | 47.31 | 9.634 | 9.766 | 9.685 | 29 | 1.756 | 1.765 | 1.758 | 3.043 | 3.053 | 3.044 | 1.479 | 1.507 | 1.504 | 30 | 0.019 | 0.021 | 0.019 | 0.003 | 0.017 | 0.004 | 0.023 | 0.035 | 0.023 | 31 | 0.019 | 0.022 | 0.019 | 0.003 | 0.011 | 0.003 | 0.023 | 0.027 | 0.023 | 32 | 0.253 | 0.255 | 0.253 | 0.072 | 0.08 | 0.073 | 0.056 | 0.067 | 0.057 | 33 | 0.039 | 0.042 | 0.039 | 0.015 | 0.025 | 0.015 | 0.015 | 0.02 | 0.015 |
测试说明
以下说明对应于上表列出的测试:
• | (1) EnterCriticalSection 使用优先级倒置的传统阻塞时间:从较低优先级线程调用 LeaveCriticalSection 直到等待 EnterCriticalSection 调用的较高优先级线程被解除阻塞的时间。 | • | (2) EnterCriticalSection 没有优先级倒置的传统阻塞时间:在较高优先级线程调用 EnterCriticalSection(被阻塞)直到较低优先级线程被释放后开始运行之间的时间。 | • | (3) EnterCriticalSection 快速路径:非竞争调用 EnterCriticalSection。 | • | (4) LeaveCriticalSection 快速路径:非竞争调用 LeaveCriticalSection。 | • | (5) 使用倒置和 CacheSync 的 EnterCriticalSection:从较低优先级线程调用 LeaveCriticalSection 直到等待 EnterCriticalSection 调用的较高优先级线程被解除阻塞的时间。 | • | (6)没有优先级倒置和 CacheSync 的 EnterCriticalSection 传统阻塞时间:从较高优先级线程调用 EnterCriticalSection(被阻塞)直到较低优先级线程被释放后开始运行的时间。 | • | (7) 进程内事件:从一个线程中的 SetEvent 函数通知事件直到被阻塞在相同进程内的 WaitForSingleObject 的线程被释放的时间。 | • | (8) 进程间事件:从一个线程中的 SetEvent 通知事件直到被阻塞在不同进程内的 WaitForSingleObject 的线程被释放的时间。 | • | (9) 有 CacheSync 的进程内事件:从一个线程中的 SetEvent 通知事件直到被阻塞在相同进程中的 WaitForSingleObject 的线程被释放的时间。 | • | (10) 有 CacheSync 的进程间事件:从一个线程中的 SetEvent 通知事件直到被阻塞在不同进程中的 WaitForSingleObject 的线程被释放的时间。 | • | (11) 通知进程内的信号量:从较低优先级线程调用 ReleaseSemaphore 直到被阻塞在相同进程中的 WaitForSingleObject 的较高优先级线程被释放的时间。 | • | (12) 通知进程间的信号量:从较低优先级线程调用 ReleaseSemaphore 直到被阻塞在不同进程中的 WaitForSingleObject 的较高优先级线程被释放的时间。 | • | (13) 有 CacheSync 的通知进程内的信号量:从较低优先级线程调用 ReleaseSemaphore 直到被阻塞在相同进程中的 WaitForSingleObject 的较高优先级线程被释放的时间。 | • | (14) 有 CacheSync 的通知进程间的信号量:从较低优先级线程调用 ReleaseSemaphore 直到被阻塞在不同进程中的 WaitForSingleObject 的较高优先级线程被释放的时间。 | • | (15) 进程内 Mutex:从较低优先级线程调用 ReleaseMutex 直到被阻塞在相同进程中的 WaitForSingleObject 的较高优先级线程被释放的时间。 | • | (16) 进程间 Mutex:从较低优先级线程调用 ReleaseMutex 直到被阻塞在不同进程中的 WaitForSingleObject 的较高优先级线程被释放的时间。 | • | (17) 有 CacheSync 的进程内 Mutex:从较低优先级线程调用 ReleaseMutex 直到被阻塞在相同进程中的 WaitForSingleObject 的较高优先级线程被释放的时间。 | • | (18) 有 CacheSync 的进程间 Mutex:从较低优先级线程调用 ReleaseMutex 直到被阻塞在不同进程中的 WaitForSingleObject 的较高优先级线程被释放的时间。 | • | (19) 进程内线程计时的收益:从线程调用 Sleep(0) 直到相同进程中相同优先级的线程从前面的 Sleep(0) 调用中苏醒过来的时间。 | • | (20) 进程间线程计时的收益:从线程调用 Sleep(0) 直到不同进程中相同优先级的线程从前面的 Sleep(0) 调用中苏醒过来的时间。 | • | (21) 有 CacheSync 的进程内线程计时的收益:从线程调用 Sleep(0) 直到相同进程中相同优先级的线程从前面的 Sleep(0) 调用中苏醒过来的时间。 | • | (22) 有 CacheSync 的进程间线程计时的收益:从线程调用 Sleep(0) 直到不同进程中相同优先级的线程从前面的 Sleep(0) 调用中苏醒过来的时间。 | • | (23) 进程内系统 API 调用(往返):不带参数地调用一个作为当前进程一部分的系统 API 并让调用立即返回所需的时间。 | • | (24) 进程内系统 API 调用(往返):使用 7 个 DWORD 参数调用一个作为当前进程一部分的系统 API 并让调用立即返回所需的时间。 | • | (25) 进程内系统 API 调用(往返):使用 7 个 PVOID 参数调用一个作为当前进程一部分的系统 API 并让调用立即返回所需的时间。 | • | (26) 进程间系统 API 调用(往返):不带参数地调用一个在不同进程中的系统 API 并让调用立即返回所需的时间。 | • | (27) 进程间系统 API 调用(往返):使用 7 个 DWORD 参数调用一个在不同进程中的系统 API 并让调用立即返回所需的时间。 | • | (28) 进程间系统 API 调用(往返):使用 7 个 PVOID 参数调用一个在不同进程中的系统 API 并让调用立即返回所需的时间。 | • | (29) 对 Nk.exe 的系统 API 调用(往返):调用内核中的系统 API 并立即返回所需要的时间。 | • | (30) InterlockedIncrement:调用 InterlockedIncrement API 的时间。 | • | (31) InterlockedDecrement:调用 InterlockedDecrement API 的时间。 | • | (32) InterlockedExchange:调用 InterlockedExchange API 的时间。 | • | (33) InterlockedTestExchange:调用 InterlockedTestExchange API 的时间。 |
小结
尽管以前的 Windows CE 版本提供了某些实时 OS (RTOS) 功能,但自从 Windows CE 3.0 以来对内核的很多重大更改已经极大地增强了实时性能。正如本文已经介绍的内容,对 Windows CE .NET 作了以下更改:
• | 增加了线程优先级级别的数目(从 8 到 256) | • | 更多地控制时间和调度。应用程序可以控制提供给每个线程的时间,并操纵对它们有好处的计划程序。现在,对于与休眠和等待相关的 API,计时器精确到一毫秒。 | • | 处理优先级倒置的方法得到改进。 | • | 全面支持嵌套中断。 | • | ISR 和 IST 滞后时间得到减少。 | • | 更细粒度的内存管理控制。 | • | 在 x86 平台上,能够通过 OEM 定义的变量指定页面池表大小。 |
本文还描述了用来测试内核的实时性能的工具(ILTiming 和 OSBench),并提供了在三种 CPU 上的实时性能测试结果。
更多信息
有关 Windows Embedded 系列的详细信息,请参阅 Windows Embedded Web 站点。
|