新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论.NET,C#,ASP,VB技术
    [返回] 中文XML论坛 - 专业的XML技术讨论区计算机技术与应用『 Dot NET,C#,ASP,VB 』 → 穷人的电源监视器 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 5174 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: 穷人的电源监视器 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 Dot NET,C#,ASP,VB 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客楼主
    发贴心情 穷人的电源监视器

    目前,便携式计算机的销量已经超过了台式计算机,其意义重大。这意味着用户具有更多的移动性,可以坐在会议室、咖啡厅或飞机上使用应用程序。它还意味着您一天的绝大部分工作可以远离为便携式计算机供电的壁装电源插座。在长途飞行中,我总希望电池能够一直支撑到目的地,因此,我经常会意识到在长途飞行中我所付出的是什么。然而,我是凭直觉和环境要求来选择应用程序的。例如,如果电扇在运转,并且应用程序性能不够好,我就知道系统负载过重,而电池将比预期更早用完。然而,我希望有些事情更科学一些,而不是仅仅将手放在机器上,努力去感觉电流的强度。确实有一些完善的软件能够检测各种应用程序的电源使用情况,仅通过监视一些关键的性能计数器,我就能计算出这些应用程序较为近似的耗电率。

    统计
    首先,您知道 CPU 全负荷运行时会消耗很多电能。硬盘是所用的又一耗电设备,因此,物理磁盘 IO 是另一提示。最后,使用网络,尤其是使用无限网络,都会显著地消耗电能。当然,还有一些其他的重要因素(例如,您的设备亮度始终调节得较高),但是,这其中的很多信息通过软件确实无法检测到,因而就从总计的耗电量中遗漏掉了。即便如此,我仍相信本文所研究的电源监视器能够为您提供关于电源消耗速度的很好提示。

    应用程序
    我希望有一种应用程序真的能够让我非常轻松地知道所消耗的电能,尤其是电能都用在了哪里,因此开发了以下用户界面:

    按此在新窗口浏览图片


    当我在压缩包含 SQL 2000 的目录的同时通过无线网络下载 ISO 图像时,就是在消耗电能。您可以看到,系统很忙碌,并且电源使用监视器显示 CPU、磁盘以及网络连接子系统都在压力下工作。停止下载操作,网络连接使用就会下降:

    按此在新窗口浏览图片


    停止压缩操作,系统会返回到更为空闲的状态:

    按此在新窗口浏览图片


    还要注意那条蓝色的竖线。它表示最后一分钟的平均耗电量。由于在运行应用程序时电能使用会尝试跳跃到平均值附近,因此,通过这条蓝色的竖线,您可以看到瞬间的平均电能使用情况。

    详细信息
    该应用程序使用计时器控件以每两秒钟一次的频率定期轮询某些特定的系统计数器。对于 CPU 数据,这一操作非常简单,仅使用 .NET Framework 的 PerformanceCounter 类即可。而对于磁盘 IO,这一操作则略为复杂。我希望读取的计数器是 Physical Disk:% Disk Time:_Total 计数器。然而遗憾的是,正如[URL=http://support.microsoft.com/default.aspx?scid=kb;en-us;324548]此处[/URL]所记录的,在 1.0 和 1.1 版中从 .NET Framework 读取该计数器被中断,而在 2.0 版中显然还存在这样的问题。然而,仅仅使用一些 WMI 代码,您就可以轻松地得到如下信息:

    physDiskCounter = new
    ManagementObject("Win32_PerfRawData_PerfDisk_PhysicalDisk.Name='_Total'");
    physDiskCounter.Get();
    double newCountBase = (double)(ulong)
    physDiskCounter.Properties["PercentDiskTime_Base"].Value;
    double newCountValue = (double)(ulong)
    physDiskCounter.Properties["PercentDiskTime"].Value;
    double result = ((prevCountValue - newCountValue) /
    (prevCountBase - newCountBase)) * 100;
    prevCountBase = newCountBase;
    prevCountValue = newCountValue;
    return result;

    这只是访问原始性能计数器值,从中减去以前的值得到增加值,然后返回结果。

    读取网络信息也存在问题,但其原因并不相同。首先,我确实希望只监视无线网卡,因为无线网卡最消耗电能。当然,我不希望诸如环回适配器之类的硬件也消耗电能。我可以使用一些较低级别的 API 来查找无线网络适配器,但是,幸运的是,2.0 版的 Framework 含有一些新的网络类,可以简化上述操作:

    // Look for a "real" network interface, and preferably
    // a WiFi, as it uses the most power.
    NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces();
    foreach (NetworkInterface ni in interfaces)
    {
    if (ni.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 ||
    ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
    {
    netName = ni.Description.Replace("(", "[").Replace(")", "]");
    speed = ni.Speed / 10;
    if (ni.NetworkInterfaceType == NetworkInterfaceType.Wireless80211)
    {
    break;
    }
    }
    }

    可以看到 NetworkInterface 类公开了关于每个网络接口的大量信息。尤其是它能够很轻松地查找到 802.11 接口。然而(没有任何事情永远都是轻而易举能做到的),此方法返回基于 Intel 21140 的 PCI Fast Ethernet Adapter(通用)- Packet Scheduler Miniport,以便于对适配器进行描述。但是,其显示的实名却为 Intel 21140-Based PCI Fast Ethernet Adapter [Generic] - Packet Scheduler Miniport。注意单词“通用”所使用的是方括号,而不是圆括号。我不能确定 NetworkInterface API 返回圆括号的原因,但是,如果尝试使用 PerformanceCounter 类或 WMI 来读取该计数器,系统将不会发现上述实名,因为上述名称确实并不匹配。

    我还遇到过与 PerformanceCounter 有关的另一问题。 从外表上看,好像是将上述实例名称截断为 64 个字符,所以,在我使用 Intel 21140-Based PCI Fast Ethernet Adapter [Generic] - Packet Scheduler Miniport 时,系统只采用 Intel 21140-Based PCI Fast Ethernet Adapter [Generic] - 数据包 S。最后面的 17 位字符被删除,并且 PerformanceCounter 类引发异常,显示其无法找到我所查找的内容。

    新(相对)的 MSDN Product Feedback Center 填补了这项空白。我使用它来查找错误,结果发现此错误[URL=http://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx?feedbackid=00cc94e9-274b-43e6-bb5f-f4592ff21ee7]已报告[/URL],并且计划将在 Visual Studio 2005 的 Beta 版本中予以修复。

    最后,此错误也返回到 WMI 以读取该性能计数器。

    这很平稳
    此时,我能够读取全部适用的性能计数器,并且到了应该提供信息的时候了。读取性能计数器时,我不希望经常读取这些计数器,因为读取性能计数器的开销相对较高。然而,如果您的条线图的更新速率仅为每两秒钟一次,那么此条线图可能会有较大跳跃,因此很难看清您此刻实际使用的电量(读取的较高,下一个可能较低)。我希望条线图的运动曲线变得平滑,因此,使用一个附加的计时器控件,该计时器控件每秒钟标记 10 次,以使最后一次性能计数器读数和当前的性能计数器读数之间的条线图增加。其影响如下所示:

    按此在新窗口浏览图片


    解决方案本身就是问题
    同样,您不希望您的电源监视器自身消耗很多电能。此应用程序在运行时消耗 CPU 所消耗电量的 6%。对于我来说,这种开销太高。为解决这个问题,我修改了该应用程序,以便在其最小化时,它使用系统任务栏图标来显示电源使用图,同时显示逻辑电路,此应用程序耗电量较低。

    降低一些应用程序耗电量确实有效的方法是,如果该应用程序不可见,则停止提供逻辑电路。这一操作确实非常简单(但是几乎没有任何应用程序会采取此方法,对此您可能会感到奇怪):

    if (Visible)
    {
    int x = pictureBox1.Width;
    int y = pictureBox1.Height;
    using (Graphics g = pictureBox1.CreateGraphics())
    {
    Render(g, x, y);
    }
    }

    换句话说,如果该窗体不可见,则不要在其上呈现条线图。仅这一更改就可将电能消耗从占 CPU 的 6% 下降到占 CPU 的 2% 左右。最小化应用程序时,此应用程序仍使用通知图标控件为系统任务栏提供条线图:

    Bitmap iconBitmap = new Bitmap(16, 16);
    using (Graphics g = Graphics.FromImage(iconBitmap))
    {
    Render(g, 16, 16);
    try
    {
    notifyIcon1.Icon = Icon.FromHandle(iconBitmap.GetHicon());
    }
    catch (Exception)
    {
    }
    }

    正如您所看到的,可以非常容易地生成位图,然后使用 GetHicon 方法在通知图标中显示位图。为系统任务栏提供 256 像素的图像所消耗的电能比为该窗体提供 11500 像素图像消耗的电能少很多。

    然而,我很快注意到另一问题:由于通知图标只是分辨率不同,您并没有看到其中以每秒钟 10 次的速率进行的物理变化,因此,我意识到最小化电源监视器后,可以降低呈现速率:

    private void Form1_VisibleChanged(object sender, EventArgs e)
    {
    renderTimer.Interval = Visible ? 100 : 500;
    }

    随着这些更改的生效,最小化后,电源监控器现在所消耗的平均电能不到 CPU 消耗电能的 1%,同时还能提供总计电能使用情况的直观指示。通过简单的双击操作就可以显示有关详细信息的完整窗体。此时耗电量非常低,因此即使让电源监控器一直运行也不会显著影响电池的使用寿命。

    此时,我可以使用一个应用程序来轻松地对运行什么作出智能选择,从而节省电能。此外,尽管该应用程序并不监视单个进程,但我发现它对于识别耗电量高的进程很有帮助。

    Sean Campbell,[URL=http://www.3leafdev.com/]3 Leaf Development[/URL]

    [URL=http://msdn.microsoft.com/coding4fun/inthebox/powermonitor/default.aspx]转到原英文页面[/URL]


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2008/2/1 15:13:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 Dot NET,C#,ASP,VB 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/12/27 1:06:50

    本主题贴数1,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    62.988ms