Уменьшите энергопотребление своего компьютера с помощью интеллектуальных мониторов активности

Мониторинг использования приложений, системных атрибутов и действий пользователя с целью более эффективного управления энергопотреблением вашего ноутбука или настольного компьютера

Узнайте о том, как сократить энергопотребление компьютера под управлением Linux® посредством мониторинга шаблонов использования приложений и действий пользователя.

Натан Харрингтон, программист, IBM

Фото автораНатан Харингтон (Nathan Harrington) - программист в IBM, работающий в настоящее время с Linux и с технологиями поиска ресурсов.



07.08.2009

Интерфейс ACPI (Advanced Configuration and Power Interface) и системы управления энергопитанием, встроенные в современные компьютеры, предоставляют обширный набор возможностей для сокращения общего потребления энергии. Операционная система Linux и сопутствующие пользовательские программы располагают большим числом инструментов, позволяющих управлять энергопотреблением персонального компьютера в самых различных сценариях.

Большая часть современной документации ориентируется на изменение параметров ядра и настроек утилиты hdparm с целью уменьшения объема ненужной дисковой деятельности. Кроме того, имеется обширная документация по изменению настроек процессора с целью максимального использования преимуществ динамического масштабирования его тактовой частоты в зависимости от текущего источника энергии.

В этой статье описываются инструменты и программы, позволяющие эффективнее использовать эти энергосберегающие механизмы посредством мониторинга шаблонов использования приложений. Используйте представленные в этой статье методы для изменения настроек энергопотребления своего компьютера в зависимости от таких факторов как находящееся в фокусе приложение, деятельность пользователя и общая производительность системы.

Требования к аппаратным средствам и программному обеспечению

Любой ПК, произведенный после 2000 г., должен располагать аппаратными и программными средствами, способными сокращать потребление энергии. Вам потребуется современное ядро ОС Linux, кроме того, полезно иметь дистрибутив Linux с большим числом встроенных инструментов для экономии энергии. Однако даже такие простейшие меры как гашение экрана или автоматическое выключение способны обеспечить существенный эффект с точки зрения потребления энергии. Представленный в этой статье код окажется полезным и для более старых или не поддерживающих ACPI аппаратных средств.

Хотя этот код демонстрируется на персональном компьютере, серверы или удаленные терминалы также смогут использовать эти концепции для регулирования своего энергопотребления в соответствии с пользовательской активностью.


Программа focusTracker.pl

Сокращение расхода энергии на основе мониторинга использования приложений может быть реализовано в различной форме. В этой статье используется следующая концепция. Сначала осуществляется выявление характерных шаблонов использования, сопровождаемых «потерями» энергии, после чего инициализируется соответствующий режим экономии энергии. В листинге 1 приведен фрагмент программы focusTracker.pl с кодом для начала процесса выявления.

Листинг 1. Заголовок программы focusTracker.pl
#!/usr/bin/perl -w
# focusTracker.pl - collect focus data for usage visualizations
use strict;
use X11::GUITest qw( :ALL );    # find application focus
use threads;                    # non blocking reads from xev
use Thread::Queue;              # non blocking reads from xev
$SIG{INT} = \&printHeader;      # print header file to stderr on exit

$|=1;                # non-buffered output
my %log = ();        # focus tracking data structure
my $lastId = "";     # last focused window id
my $pipe = "";       # non blocking event reads via xev
my @win = ();        # binary activity data for maxWindows applications
my $cpu = "";        # cpu usage from iostat
my $mbread_s = "";   # disk read mb/s from iostat
my $totalWindow = 0; # total used windows
my $maxWindows = 50; # total tracked windows

В дополнение к необходимым элементам этот модуль содержит описания переменных; в частности, определен фиксатор (catcher) для сигналов о прерывании, что позволяет выводить на печать ассоциированный заголовок для каждого прогона данных. Такое разделение файлов данных и файлов заголовков упрощает визуализацию результатов при использовании таких инструментов как kst. В листинге 2 приведено начало основного цикла обработки.

Листинг 2. Начало основного цикла программы focusTracker.pl
while(my $line = <STDIN> )
{
  for my $c (0..$maxWindows){ $win[$c] = 0 }  #initialize all data positions

  next if( $line =~ /Linux/ || length($line) < 10 ); # header line, empty line

  my $windowId   = GetInputFocus();
  my $windowName = GetWindowName( $windowId ) || "NoWindowName";

  if( ! exists($log{$windowId}) )
  {
    # if this is a new window, assign it to the next position in the data set 
    $log{ $windowId }{ order } = $totalWindow;
    $log{ $windowId }{ name }  = $windowName;
    $totalWindow++ if( $totalWindow < $maxWindows );

  }# if a newly tracked window

В каждом чтении из stdin текущие двоичные данные о фокусе (хранящиеся в @win) устанавливаются в состояние 0. Каждый раз, когда какое-либо окно получает фокус, которого у него не было до этого, положение и имя этого окна записываются в хеш %log. Этот шаг имеет ключевое значение для корректного ассоциирования данных «в фокусе»/«не в фокусе» с соответствующим именем окна. В листинге 3 показано продолжение чтения входной информации и начало управления конвейером.

Листинг 3. Управление конвейером программы focusTracker.pl
  if( $line =~ /avg-cpu/ )
  {
    # read the CPU usage, transform to 2-12 value for visualization
    ( $cpu ) = split " ", <STDIN>;
    $cpu = sprintf("%2.0f", ($cpu /10) + 2 );

  }elsif( $line =~ /Device/ )
  {
    # read the disk reads, transform to 2-12 value for visualization
    ( undef, undef, $mbread_s ) = split " ", <STDIN>;
    $mbread_s = $mbread_s * 10;
    if( $mbread_s > 10 ){ $mbread_s = 10 }
    $mbread_s = sprintf("%2.0f", $mbread_s + 2);

    # check focus information
    if( $windowId ne $lastId )
    {
      if( $lastId ne "" )
      {
        # close old pipe
        my $cmd = qq{ps -aef | grep $lastId | grep xev | perl -lane '`kill \$F[1]`'};
        system($cmd);
      }
      $lastId = $windowId;
  
      # open new pipe
      my $res = "xev -id $windowId |";
      $pipe = createPipe( $res ) or die "no pipe ";

После того как чтение данных об использовании центрального процессора и диска будет завершено, показатели использования преобразуются в серию значений в масштабе 2-12. Это делается исключительно с целью визуализации. При наличии нескольких центральных процессоров или дисков Fibre Channel может потребоваться изменение масштаба преобразования. Указанные в этой статье значения хорошо работают при использовании одного центрального процессора и одного IDE-диска на ноутбуке IBM® ThinkPad T42p.

Если между чтениями входных данных положение фокуса изменилось, старый конвейер к процессу xev «ликвидируется» и запускается новый конвейер. Программа xev, прикрепленная к текущему окну с фокусом, отслеживает любые нажатия клавиш или движения мыши. В листинге 4 показано, как осуществляется обработка этих событий.

Листинг 4. Чтение конвейера focusTracker.pl
    }else
    { 
      # data on the pipe indicates activity
      if( $pipe->pending )
      { 
        for my $c (0..$maxWindows){ $win[$c] = 0 }  #initialize all data positions
        $win[ $log{$windowId}{order} ] = 1;
        
        # clear the pipe
        while( $pipe->pending ){  my $line = $pipe->dequeue or next }
      
      }#if events detected for that window
    
    }#if pipe settings
    
    # CPU usage, disk reads, focus tracking data    
    print "$cpu $mbread_s @win \n";
  
  }#if device line

}#while input

Доступ к этому логическому блоку производится только в том случае, если фокус приложения не меняется в промежутке между чтениями входной информации. Если в конвейере присутствуют данные (нажатие клавиши или движение мыши) от приложения «в фокусе», то для этого приложения устанавливается соответствующее двоичное состояние деятельности. Для очистки конвейера достаточно прочитать все выходные строки xev. После каждого полного цикла ввода осуществляется вывод на печать информации об использовании центрального процессора и диска, а также двоичных данных о фокусе. В листинге 5 приведена подпрограмма createPipe, используемая для создания неблокирующей связи с программой мониторинга xev, и подпрограмма printHeader, которая «печатает» информацию заголовка данных в поток STDERR.

Листинг 5. Подпрограммы focusTracker.pl
sub createPipe
{ 
  my $cmd = shift;
  my $queue = new Thread::Queue;
  async{ 
      my $pid = open my $pipe, $cmd or die $!;
      $queue->enqueue( $_ ) while <$pipe>;
      $queue->enqueue( undef );
  }->detach;
  
  # detach causes the threads to be silently terminated on program exit
  return $queue;

}#createPipe

sub printHeader
{
  for my $key ( sort { $log{$a}{order} <=> $log{$b}{order} } keys %log )
  {
    print STDERR "$log{$key}{order} $key $log{$key}{name} \n";
  }
}#printResult

Использование программы focusTracker.pl

Программа focusTracker.pl ожидает ввода данных из программы iostat с регулярными интервалами. В листинге 6 приведен пример командной строки для записи информации об использовании приложения.

Листинг 6. Пример команды focusTracker.pl
iostat -m -d -c 1 | \
  perl focusTracker.pl 2> activityLog.header | tee activityLog.data

Нажмите комбинацию клавиш Ctrl+C, чтобы прервать выполнение программы focusTracker.pl. Обратите внимание, что символ \ предназначен только для продолжения текущей строки и не должен использоваться внутри командной строки. Ключ -m дает программе iostat указание отображать значения в мегабайтах в секунду (где это применимо), ключ –d задает отображение информации об устройстве (в данном случае – это пропускная способность диска), ключ -c определяет, какую информацию об использовании центрального процессора следует показывать. Заключительная опция (1) дает программе iostat указание отображать новую информацию каждую секунду. В листинге 7 приведен пример результатов работы этой команды, а также строки из файла заголовка, которые печатаются в файл activityLog.header, когда пользователь нажимает комбинацию клавиш Ctrl+C.

Листинг 7. Пример результатов работы программы focusTracker.pl
 5  2 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
 6  2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 9  2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 5  2 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 7  2 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
...
0 10485764 NoWindowName 
1 33554434 Eterm 
2 44040194 Eterm 
3 41943042 focusTracker.pl (~/smartInactivityDetector) - VIM 
4 27263164 Controlling ACPI Centrino features - Mozilla Firefox

Обратите внимание, как второй и пятый элементы показывают информацию о фокусе для окон приложений Eterm и Firefox. Переключение между окнами и ввод с клавиатуры/перемещение мыши заставит индикатор фокуса соответствующего окна переключиться из состояния «0» в состояние «1».

Исполнение программы focusTracker на протяжении коротких промежутков времени в присутствии пользователя – это хороший способ для сбора данных по использованию приложений и по бездействию компьютера. В качестве альтернативного варианта можно исполнять программу focusTracker.pl на протяжении всей вычислительной сессии или всего рабочего дня с целью получения большого объема данных для последующих процедур анализа и визуализации.


Визуализация использования

Для обработки больших объемов данных, генерируемых программой focusTracker.pl, лучше всего подходят такие инструменты как kst. На рисунке 1 показан пример анализа данных из файла activityLog.data.

Рисунок 1. Пример визуализации с помощью kst
Рисунок 1. Пример визуализации с помощью kst

При генерации показанного выше графика использование центрального процессора и диска представлено с помощью линий, а двоичные данные о фокусе для каждого приложения представлены отдельными точками. Начиная примерно с точки 196 по оси X, фокус находится у приложения Firefox, результатом чего является пик активности центрального процессора и диска. Эта деятельность не сопровождается последующими входными событиями, поэтому после нее следует возвращение к «нормальному» использованию центрального процессора и диска.

В этот момент внешний наблюдатель за пользователем данного компьютера увидел бы переход от написания кода в различных окнах Eterm к загрузке в приложение Firefox страницы с информацией о локальном трафике. После этого пользователь покинул свой компьютер и ушел на обеденный перерыв.

Типовая настройка управления энергопотреблением для данной ситуации сводится к активации экранной заставки после истечения заданной продолжительности бездействия системы. Знание описанных выше шаблонов использования позволяет задать следующее правило: если приложение Firefox было активировано в период между 11:30 и 12:30, и при этом имела место лишь кратковременная активность пользователя, то система должна переключаться в режим низкого энергопотребления.

Кроме того, рассмотрим низкий уровень использования центрального процессора и диска, соответствующий работе с приложением Eterm/vim. Активация режима пониженного энергопотребления в данном случае будет вполне логичным шагом, поскольку для ввода текста в vim не требуется большой процессорной мощности. Уменьшение скорости вращения жесткого диска и снижение частоты центрального процессора может быть реализовано для любого промежутка времени, на протяжении которого активность центрального процессора и диска находится ниже заданного порога.

Настройка inactivityRulesFile

Описанные выше правила могут быть кодифицированы следующим образом (листинг 8).

Листинг 8. Пример правил inactivityRulesFile
# format is:
# start end CPU disk timeOut application command
1130_#_1230_#_null_#_null_#_10_#_firefox_#_xscreensaver-command -activate
0610_#_1910_#_6_#_2_#_30_#_vim_#_echo 6 > /proc/acpi/processor/CPU0/performance

Примечание. Если требуется только проверка деятельности пользователя, то значения для центрального процессора и диска могут быть заданы как null. Если значения для центрального процессора и диска определены, то в дальнейшем они рассматриваются как минимальные значения использования, которые должны быть достигнуты для запуска команды на исполнение. Переменная timeOut определяет продолжительность бездействия пользователя (в секундах), после которого осуществляется проверка минимумов центрального процессора и диска. Переменная приложения позволяет специфицировать любой текст в заголовке приложений в системе X Window.


Программа monitorUsage.pl

Обработка файла inactivityRulesFile и измерение использования приложений в системе – это функции программы monitorUsage.pl. В листинге 9 приведена первая часть этой программы.

Листинг 9. Заголовок программы monitorUsage.pl
#!/usr/bin/perl -w
# monitorUsage.pl - track application usage patterns and run commands
use strict;
use X11::GUITest qw( :ALL );    # find application focus
use threads;                    # non blocking reads from xev
use Thread::Queue;              # non blocking reads from xev
    
$|=1;               # non-buffered output
my $cpu = "";       # CPU usage from iostat
my $mbread_s = "";  # disk read mb/s from iostat
my @rules = ();     # rules from inactivityRulesFile
my $ruleCount = 0;  # total rules
my $lastId = "";    # last focused window id 
my $pipe = "";      # non blocking event reads via xev
my %app = ();       # current focused app attributes
    
open(INFILE," inactivityRulesFile") or die "can't open rules file";
  while( my $line = <INFILE> )
  { 
    next if( $line =~ /^#/ );        # skip comment lines
    my( $start, $stop, $cpu, $disk, 
        $timeOut, $appName, $cmd ) = split "_#_", $line;
      
    $rules[$ruleCount]{ start }   = $start;
    $rules[$ruleCount]{ stop }    = $stop;
    $rules[$ruleCount]{ cpu }     = $cpu;
    $rules[$ruleCount]{ disk }    = $disk;
    $rules[$ruleCount]{ timeOut } = $timeOut;
    $rules[$ruleCount]{ appName } = $appName;
    $rules[$ruleCount]{ cmd }     = $cmd;
    $ruleCount++;
      
  }#while infile
      
close(INFILE);

Как и в случае программы focusTracker.pl, в программу включены библиотеки и определения переменных. Контент файла inactivityRulesFile загружается в хеш %rules для последующей обработки. В листинге 10 показана обработка входной информации от iostat и проверка фокуса.

Листинг 10. Программа monitorUsage.pl – чтение данных; управление конвейером
while(my $line = <STDIN> )
{
  next if( $line =~ /Linux/ ); # header line;

  next if( length($line) < 10 ); # any blank line

  my $windowId = GetInputFocus();
  my $windowName = GetWindowName( GetInputFocus() ) || "NoWindowName";

  if( $line =~ /avg-cpu/ )
  {
    ( $cpu ) = split " ", <STDIN>;
    $cpu = sprintf("%2.0f", ($cpu /10) + 2 );

  }elsif( $line =~ /Device/ )
  {
    #read the disk reads, transform to 2-12 value for visualization
    ( undef, undef, $mbread_s ) = split " ", <STDIN>;
    $mbread_s = $mbread_s * 10;
    if( $mbread_s >10 ){ $mbread_s = 10 }
    $mbread_s = sprintf("%2.0f", $mbread_s + 2);

    if( $windowId ne $lastId )
    { 
      if( $lastId ne "" )
      { 
        # close old pipe
        my $cmd = qq{ps -aef | grep $lastId | grep xev | perl -lane '`kill \$F[1]`'};
        system($cmd);
      }
      $lastId = $windowId;

      # open new pipe
      my $res = "xev -id $windowId |";
      $pipe = createPipe( $res ) or die "no pipe ";

      # reset currently tracked app
      %app = ();
      $app{ id }           = $windowId;
      $app{ name }         = $windowName;
      $app{ cmdRun }       = 0;
      $app{ lastActivity } = 0;

В данном случае потребность в отслеживании нескольких приложений отсутствует, поэтому хеш %app просто отслеживает атрибуты приложения, которому в текущий момент времени принадлежит фокус. В листинге 11 показан логический переход, когда то же самое приложение обладает фокусом в результате многократного чтения входной информации.

Листинг 11. Чтение конвейера monitorUsage.pl
    }else
    {
      # data on the pipe indicates activity 
      if( $pipe->pending )
      { 
        # clear the pipe
        while( $pipe->pending ){ my $line = $pipe->dequeue or next }

        $app{ cmdRun } = 0;
        $app{ lastActivity } = 0;

Проверка на соответствие правилам и выполнение команд осуществляется только в том случае, когда приложения являются неактивными; таким образом, любая активность со стороны клавиатуры или мыши перезагружает таймеры бездеятельности приложений. Вызов приведенного в листинге 12 кода осуществляется в том случае, если в конвейере отсутствуют какие-либо данные об активности пользователя.

Листинг 12. Проверка правил в программе monitorUsage.pl
      }else 
      {
        $app{ lastActivity }++;
        print "no events for window $windowName last "
        print "activity seconds $app{lastActivity} ago\n";
      
        my $currTime = `date +%H%M`;

        for my $ruleNum ( 0..$ruleCount-1)
        {
          next unless( $app{cmdRun} == 0 );

          next unless( $windowName =~ /$rules[$ruleNum]{appName}/i );

          next unless( $app{lastActivity} >= $rules[$ruleNum]{timeOut} );

          next unless( $currTime >= $rules[$ruleNum]{start} &&
                       $currTime <= $rules[$ruleNum]{stop} );

          my $conditions = 0;
          $conditions++ if( $rules[$ruleNum]{cpu}  eq "null" );

          $conditions++ if( $rules[$ruleNum]{disk} eq "null" );

          $conditions++ if( $rules[$ruleNum]{cpu}  ne "null" &&
                            $rules[$ruleNum]{cpu}  <= $cpu );

          $conditions++ if( $rules[$ruleNum]{disk} ne "null" &&
                            $rules[$ruleNum]{disk} <= $mbread_s );

          next unless( $conditions > 1 );

          print "running $rules[$ruleNum]{cmd}\n";
          $app{ cmdRun } = 1;
          system( $rules[$ruleNum]{cmd} );

        }#for each rule to process

      }#if events detected for that window

    }#if pipe settings

  }#if device line

}#while input

Обработка правил осуществляется согласно показанному выше списку и для каждого правила начинается с проверки, призванной гарантировать, что команда данного правила еще не выполнялась. После этого выполняется проверка на соответствие имени окна и имени правила для приложения. Затем должна быть достигнута общая продолжительность бездействия (в секундах), а также активизировано окно истинного времени для подлежащей выполнению команды. И, наконец, если условия для центрального процессора и диска выполнены, то соответствующая команда исполняется, после чего осуществляется обработка следующего правила. В листинге 13 приведена уже знакомая нам подпрограмма createPipe, необходимая для завершения программы monitorUsage.pl.

Листинг 13. Подпрограмма createPipe программы monitorUsage.pl
sub createPipe
{ 
  my $cmd = shift;
  my $queue = new Thread::Queue;
  async{ 
      my $pid = open my $pipe, $cmd or die $!;
      $queue->enqueue( $_ ) while <$pipe>;
      $queue->enqueue( undef );
  }->detach;
  
  # detach causes the threads to be silently terminated on program exit
  return $queue;

}#createPipe

Использование программы monitorUsage.pl

Исполняйте программу monitorUsage.pl с параметрами iostat-m-d-c 1 | perl monitorUsage.pl. При необходимости тестирования можно модифицировать команды inactivityRulesFile с целью исполнения таких программ как beep или xmessage, которые повышают эффективность обратной связи при достижении задаваемых вами условий. Кроме того, попробуйте модифицировать моменты начала и окончания для правил, чтобы расширить охват своих сценариев тестирования.


Заключение, дальнейшие примеры

Представленные в этой статье инструменты и программы помогут вам сократить расход энергии посредством применения набора правил, касающихся использования приложений. После настройки ядра ОС, hdparm, ACPI и параметров центрального процессора добавьте описанные мониторы приложений для повышения эффективности перехода в состояние пониженного энергопотребления. Используйте визуализацию с помощью инструментов focusTracker и kst для нахождения промежутков бездействия и создайте правила, которые помогут сократить энергопотребление и сделают вашу систему более экологичной.


Загрузка

ОписаниеИмяРазмер
Пример программного кодаos-smart-monitors-InactivityDetector.0.1.zip4KB

Ресурсы

Научиться

Получить продукты и технологии

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Open source
ArticleID=419194
ArticleTitle=Уменьшите энергопотребление своего компьютера с помощью интеллектуальных мониторов активности
publish-date=08072009