array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 eCos系统CPU负载测量 - 爱码网

原文:http://ecos.sourceware.org/docs-latest/ref/services-cpuload.html
译文:http://blog.csdn.net/zoomdy/article/details/17078995
mingdu.zheng <at> gmail <dot> com

cpuload组件包提供了一种估算CPU负载的方式。它可以估算最近0.1秒、1秒和10秒内的CPU负载百分比。

负载测量API

首先,必须在被测目标机上对测量算法进行校准,一旦校准完成后就可以开始测量。测量是一个连续过程,因此总是提供最近的测量数据,测量过程可以根据需要随时停止。一旦开始测量过程,就可以获取测量结果。

需要注意的是:如果目标机或CPU执行任何节能措施,例如降低时钟频率或者挂起CPU等,这些节能措施将干扰CPU负载测量,在这种情况下,测量结果是未定义的。Synthetic Target就是这样的情况之一。阅读本文后续实现细节章节可以了解更多。

『译注』Cortex-M架构的默认实现会在执行空闲任务时挂起CPU,因此默认情况下,测量结果并非是实际的CPU负载,需要重定义HAL_IDLE_THREAD_ACTION宏取消空闲时挂起,HAL_IDLE_THREAD_ACTION宏的默认实现位于hal/cortexm/arch/<version>/include/hal_arch.h:336。

负载测量不支持SMP系统,仅支持单CPU系统。

负载测量API可以在cyg/cpuload/cpuload.h中找到。

『译注』源代码位于services/cpuload/。

cyg_cpuload_calibrate

这个函数用来校准CPU负载测量算法。它执行一次特别的测量过程确定空闲时的CPU性能。

void cyg_cpuload_calibrate(cyg_uint32* calibration);

该函数通过calibration指针返回校准值。

这个函数是非常特别的,为了获得正确的校准结果需要满足若干条件。该函数使用了2个最高线程优先级,当该函数被使用时,其它线程不能使用这两个优先级。调用该函数时,内核调度器必须已经启动而且调度器未加锁。该函数将花费0.1秒的时间完成校准操作,在这0.1秒校准期间不能有任何其它线程执行。

『译注』这个函数使用了线程优先级1和2,为了获得正确的测量结果,其它线程不能使用优先级1和2。eCos的最高线程优先级是0,如果有优先级为0的线程,必须保证在校准过程该线程处于挂起状态,否则校准过程可能被优先级为0的线程抢占而导致错误的校准结果。

『译注』该函数将会创建一个线程,线程堆栈大小为CYGNUM_HAL_STACK_SIZE_MINIMUM,在Cortex-M架构下约1.5KB,该线程仅在校准过程执行一次,随后被删除永远都不会再执行,如果目标机内存非常有限,应当知晓CPU负载测量校准时使用了1.5KB的堆栈空间。

cyg_cpuload_create

这个函数启动CPU负载测量。

void cyg_cpuload_create(cyg_cpuload_t* cpuload,
                        cyg_uint32 calibrate,
                        cyg_handle_t* handle);

调用该函数启动测量过程,handle返回操作句柄,通过该句柄可以读取测量结果以及停止测量过程。

cyg_cpuload_delete

这个函数停止CPU负载测量。

void cyg_cpuload_delete(cyg_handle_t handle);

handle必须是cyg_cpuload_create函数返回的操作句柄。

cyg_cpuload_get

这个函数返回最近的测量结果。

void cyg_cpuload_get(cyg_handle_t handle,
                     cyg_uint32* average_point1s,
                     cyg_uint32* average_1s,
                     cyg_uint32* average_10s);

handle必须是cyg_cpuload_create函数返回的操作句柄。最近0.1秒、1秒和10秒的负载测量结果通过average_point1s、average_1s和average_10s返回。

实现细节

这一节给出一些测量过程的实现细节,这些细节可以帮助我们理解测量结果的意义。

当没有其它线程可以执行时,eCos将执行空闲线程,空闲线程总是可执行的而且使用最低线程优先级。空闲线程只做一点点事情,它有一个永远都不会退出的循环,每次循环将idle_thread_loops变量加1,然后调用HAL_IDLE_THREAD_ACTION宏。CPU负载测量算法就是使用了idle_thread_loops变量,测量算法周期性地检查idle_thread_loops变量,并记录前后两次检查的差值,系统越空这个差值就越大,通过这个简单的手段就可以确定系统的负载。

cyg_cpuload_calibrate函数执行空闲任务0.1秒,从而确定系统空闲0.1秒的时间内idle_thread_loops会被累加多少次。cyg_cpuload_create函数启动一个闹钟,这个闹钟每隔0.1秒调用回调函数,回调函数计算idle_thread_loops从上次检查到本次检查的差值,然后根据这个差值以及校准值计算出CPU负载。回调函数用新的计算结果更新cyg_cpuload结构,0.1秒负载只是简单地复制最近的测量结果,然后通过一个简单的滤波计算1秒和10秒负载。由于舍入误差的存在,即使系统满负载,1秒和10秒测量值也永远都不会达到100%,通常看到的是99%。

如前所述,电源管理代码将干扰上述测量结果。CPU负载测量的基本假设是:空闲线程可以无障碍地运行,而且运行条件与校准时的运行条件保持一致。如果降低CPU时钟频率,那么空闲线程的计数器累加速率将变慢,因此CPU负载测量结果值将偏高,如果CPU被完全挂起,那么CPU负载测量结果将是100%。

相关文章: