суббота, 21 сентября 2013 г.

BeagleBone Black - Power optimization

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

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

Основной потребитель на плате BeagleBone Black - это SoC TI Sitara AM3359. Поэтому, все действия по энергосбережению, касаются именно этого чипа. В чипе много источников  потребления - процессорное ядро ARM Cortex-A8, 2 ядра системы PRU-ICSS, ядро графического ускорителя PowerWR GSX 640. Т.к. последние две системы мы пока не используем, сосредоточимся на процессорном ядре.

Управление частотой в Linux Kernel
Если вы пишете преимущественно используя подход именуемый bare metal (на голом железе), то вы должны сами заботится об энергопотреблении. Однако, если вы работаете с железом используя систему Linux, то вы можете использовать уже готовые наработки для этого.
Вообще частота процессорного ядра может динамически меняться от 300МГц до 1ГГц, а точнее принимать одно из следующих значений - 300, 600, 800 и 1000 МГц.
Т.к. ядро Linux знает о загрузке тех или иных компонентов системы, то оно может оптимизировать потребление энергии. Существует несколько схем управления частотой процессорного ядра:

  • performance - максимальная производительность. Устанавливается максимальная частота процессорного ядра. Данная схема установлена по умолчанию (если это не было изменено в настройках ядра), также используется при питании от стационарного источника питания.
  • powersave - сохранение энергии. Устанавливается минимальная частота процессорного ядра. Используется при создании систем с низким потреблением, либо при низком уровне заряда питающей батареи.
  • userspace - управление из пространства пользователя. Используется когда потреблением управляют сторонние прикладные программы. Этот режим необходим, когда надо задать специфичное управление частотой процессорного ядра.
  • ondemand - динамическое управление, активная схема. Схема управления следующая: при возникновении загрузки с некоторой задержкой частота повышается до максимального значения, после в случае если загрузка не равна 100% от возможного, частота понижается кратно загрузке. Используется когда необходимо быстро реагировать на возникающие задачи, однако в отличие от performance имеет место некоторое замедление времени  отклика (задержка).
  • conservative - динамическое управление, пассивная схема. Схема управления отличная от ondemand: При увеличении загрузки до 100% происходит переключение частоты вверх на один диапазон, а при снижении на один диапазон вниз, с некоторой задержкой. Используется в схемах с плавным увеличением загрузки (запланированные задачи).
  • interactive (данная схема доступна по умолчанию только для Android Linux Kernel, в основной же ветке добавляется применением патча- ссылка дана для примера) - является расширением ondemand, только управление осуществляется не просто по задержке, а существует определённый план по управлению питанием устройства, куда входит и управление частотой процессорного ядра. Используется на мобильных устройствах (смартфоны, планшетные компьютеры) под управлением Android OS.
Для каждой из вышеперечисленых схем, есть свой управляющий код (governor), который назван именем схемы за которую он отвечает.

Linux Kernel - практическая база
Управление доступно из виртуальной ФС - SYSFS - /sys. Итак в списке устройств в разделе система, есть блок - процессор. В этом блоке по порядку расположены все процессорные ядра которые зарегистрированы в системе. Для каждого из ядер доступно управление частотой через интерфейс spyfreq:

# ls /sys/devices/system/cpu/cpu0/cpufreq/
affected_cpus     cpuinfo_max_freq  cpuinfo_transition_latency  scaling_available_frequencies  scaling_cur_freq  scaling_governor  scaling_min_freq  stats
cpuinfo_cur_freq  cpuinfo_min_freq  related_cpus                scaling_available_governors    scaling_driver    scaling_max_freq  scaling_setspeed

 Как видно из списка, есть набор параметров для управления и информации о частоте. Для начала просмотрим список доступных частот для процессорного ядра:

# cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies 
300000 600000 800000 1000000

Далее, можно посмотреть список доступных менеджеров управления питанием:

# cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors
conservative ondemand userspace powersave performance

Если вы не нашли нужного вам менеджера питания, то советую обратиться к разделу Power management options в настройке ядра. Узнать текущую частоту и менеджер питания также можно из этой группы:

# cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
ondemand
# cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq 
300000

Чтобы сменить менеджер питания необходимо сделать запись в соответствующий файл:

# echo 'ondemand' > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor 

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

Настройка сервисного управления питанием
Для того чтобы управление было оптимальным рекомендую использовать набор утилит sys-power/cpufrequtils. Установим его:

# emerge -av cpufrequtils

После установки необходимо настроить конфигурационный файл демона, либо оставить настройки по умолчанию:

# vim /etc/conf.d/cpufrequtils

Затем необходимо добавить демон для запуска по умолчанию:

# rc-update add cpufrequtils default

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

Получить сведения о тактовой частоте ядра и менеджере питания можно через утилиту -  cpufreq-info:

# cpufreq-info 
cpufrequtils 008: cpufreq-info (C) Dominik Brodowski 2004-2009
Report errors and bugs to cpufreq@vger.kernel.org, please.
analyzing CPU 0:
  driver: generic_cpu0
  CPUs which run at the same hardware frequency: 0
  CPUs which need to have their frequency coordinated by software: 0
  maximum transition latency: 300 us.
  hardware limits: 300 MHz - 1000 MHz
  available frequency steps: 300 MHz, 600 MHz, 800 MHz, 1000 MHz
  available cpufreq governors: conservative, ondemand, userspace, powersave, performance
  current policy: frequency should be within 300 MHz and 1000 MHz.
                  The governor "ondemand" may decide which speed to use
                  within this range.
  current CPU frequency is 300 MHz (asserted by call to hardware).
  cpufreq stats: 300 MHz:nan%, 600 MHz:nan%, 800 MHz:nan%, 1000 MHz:nan%

Для данной утилиты доступны различные режимы отображения:

# cpufreq-info --help
cpufrequtils 008: cpufreq-info (C) Dominik Brodowski 2004-2009
Report errors and bugs to cpufreq@vger.kernel.org, please.
Usage: cpufreq-info [options]
Options:
  -c CPU, --cpu CPU    CPU number which information shall be determined about
  -e, --debug          Prints out debug information
  -f, --freq           Get frequency the CPU currently runs at, according
                       to the cpufreq core *
  -w, --hwfreq         Get frequency the CPU currently runs at, by reading
                       it from hardware (only available to root) *
  -l, --hwlimits       Determine the minimum and maximum CPU frequency allowed *
  -d, --driver         Determines the used cpufreq kernel driver *
  -p, --policy         Gets the currently used cpufreq policy *
  -g, --governors      Determines available cpufreq governors *
  -r, --related-cpus   Determines which CPUs run at the same hardware frequency *
  -a, --affected-cpus  Determines which CPUs need to have their frequency
                       coordinated by software *
  -s, --stats          Shows cpufreq statistics if available
  -y, --latency        Determines the maximum latency on CPU frequency changes *
  -o, --proc           Prints out information like provided by the /proc/cpufreq
                       interface in 2.4. and early 2.6. kernels
  -m, --human          human-readable output for the -f, -w, -s and -y parameters
  -h, --help           Prints out this screen

If no argument or only the -c, --cpu parameter is given, debug output about
cpufreq is printed which is useful e.g. for reporting bugs.
For the arguments marked with *, omitting the -c or --cpu argument is
equivalent to setting it to zero

На этом всё, однако возможно, в дальнейшем я ещё раз затрону тему энергопотребления.