3

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

К сожалению, отключение ядер с помощью следующего простого подхода на самом деле увеличивает мощность, основываясь на показаниях ватт-ап?Pro измерения общей мощности системы:

echo 0 > /sys/devices/system/cpu/cpu7/online

Мой опыт, кажется, подтверждается другими (хотя эта ошибка была помечена как "ЗАКРЫТА PATCH_ALREADY_AVAILABLE"):https://bugzilla.kernel.org/show_bug.cgi?id=5471

Поскольку машина выгружена, я хочу, чтобы все, кроме одного, ядра (или, может быть, двух "ядер", поскольку ЦП является гиперпоточным) находились в максимально глубоком спящем состоянии. Похоже, что это не происходит само по себе, основываясь на выводе acpitool:

Processor ID           : 7
Bus mastering control  : no
Power management       : yes
Throttling control     : no
Limit interface        : no
Active C-state         : C0
C-states (incl. C0)    : 3
Usage of state C1      : 899 (99.3 %)
Usage of state C2      : 6 (0.7 %)

Кстати, одна из путаниц для меня в том, что acpitool и /proc /acpi, похоже, не согласны с доступными C-состояниями, или, возможно, они используют разные схемы именования.

$ cat /proc/acpi/processor/CPU7/power 
active state:            C0
max_cstate:              C8
maximum allowed latency: 2000000000 usec
states:
    C1:                  type[C1] promotion[--] demotion[--] latency[001] usage[00000000] duration[00000000000000000000]
    C2:                  type[C2] promotion[--] demotion[--] latency[017] usage[00001248] duration[00000000001877531423]
    C3:                  type[C3] promotion[--] demotion[--] latency[017] usage[00000006] duration[00000000000012580727]

Кажется, это указывает на то, что существует 4 C-состояния (C0-C3), но acpitool сообщает только о 3 C-состояниях.


На самом деле это сводится к двум вопросам:

  1. Есть ли (безопасный) способ заставить отдельные ядра перейти в определенное состояние сна (C-состояние) и заставить их оставаться там до тех пор, пока я их явно не разбуду?
  2. В качестве альтернативы, как я могу улучшить способность ОС автоматически более последовательно переводить ядра в более глубокие спящие состояния?

Обратите внимание, что задержка пробуждения от более глубоких состояний сна не является проблемой. FWIW, я использую Ubuntu 10.04.3 (ядро 2.6.32-38) на Intel i7 920.

1 ответ1

-1

Методы ограничения C-состояний, описанные выше, будут постоянными (до перезагрузки системы). Если вы хотите, чтобы у системы была чрезвычайно низкая задержка в определенные часы, но в другое время вы хотели бы сэкономить больше энергии, есть метод динамического управления тем, какие C-состояния используются.

Чтобы динамически управлять состояниями C, откройте файл /dev /cpu_dma_latency и запишите в него максимально допустимую задержку. Это предотвратит использование C-состояний с задержками перехода, превышающими указанное значение, при условии, что файл /dev /cpu_dma_latency остается открытым. Запись максимально допустимой задержки 0 будет держать процессоры в C0 (как при использовании параметра ядра «idle = poll»), а запись низкого значения (обычно 5 или ниже) должна заставить процессоры переходить в C1 в режиме ожидания. Точное значение, необходимое для ограничения процессоров до состояния C1, зависит от различных факторов, таких как, какой драйвер простоя вы используете, какие процессоры вы используете, и, возможно, таблицы ACPI в вашей системе. Более высокие значения также могут быть записаны для ограничения использования C-состояний с задержкой, превышающей записанное значение. Используемое значение должно соответствовать значениям задержки в /sys /devices /system /cpu /cpuX /cpuidle /stateY /latency (где X - номер ЦП, а Y - состояние простоя) - состояния простоя ЦПУ, которые имеют большую задержку, чем записанный в /dev /cpu_dma_latency не должен использоваться.

Один простой способ сделать это - скомпилировать простую программу, которая будет писать в этот файл и оставаться открытой, пока он не будет уничтожен. Пример такой программы приведен ниже и может быть скомпилирован путем вырезания и вставки кода в файл с именем setcpulatency.c и запуска «make setcpulatency». Таким образом, чтобы минимизировать задержку в определенные часы, скажем, с 8:00 до 17:00, задание cron может быть настроено для работы в 8:00. Это задание cron может запускать setcpulatency в фоновом режиме с аргументом 0, с записью в таблице cron:

00 08 * * * /path/to/setcpulatency 0 &

Затем в 5 часов вечера другое задание cron может убить любую программу, в которой открыт файл /dev /cpu_dma_latency:

00 17 * * * kill -9 `lsof –t /dev/cpu_dma_latency`

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

#include <stdio.h>
#include <fcntl.h>

int main(int argc, char **argv) {
   int32_t l;
   int fd;

   if (argc != 2) {
      fprintf(stderr, "Usage: %s <latency in us>\n", argv[0]);
      return 2;
   }

   l = atoi(argv[1]);
   printf("setting latency to %d us\n", l);

   fd = open("/dev/cpu_dma_latency", O_WRONLY);

   if (fd < 0) {
      perror("open /dev/cpu_dma_latency");
      return 1;
   }

   if (write(fd, &l, sizeof(l)) != sizeof(l)) {
      perror("write to /dev/cpu_dma_latency");
      return 1;
   }
}

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .