тонкая детализация nanosleep неэффективна в программе на С++ в Linux

Я пытаюсь периодически вызывать функцию выборки в потоке С++ на моей машине с Linux. Я хотел бы перезапустить свою функцию после очень короткого периода, в идеале 1 мс, но я обнаружил, что мощность (в ваттах), потребляемая в течение 1 мс, чрезмерно высока: система работает с удвоенным уровнем мощности, как когда мой период 5 мсек. Поддержание низкого энергопотребления является серьезной проблемой для функциональности, которую я хочу.

Конкретно,

void* loop_and_sample(void* arg) {
    while(1) {
      sample();
      nanosleep((struct timespec[]){{0,1000000}}, NULL);
    }
}

Принимает 2x мощность:

void* loop_and_sample(void* arg) {
    while(1) {
      sample();
      nanosleep((struct timespec[]){{0,5000000}}, NULL);
    }
}

Я определил, что разница в энергопотреблении моего сэмплера на двух частотах незначительна, и что дополнительное энергопотребление связано со спящим вызовом. То есть, даже если я закомментирую строку sample() в обоих приведенных выше фрагментах, вторая все равно будет потреблять вдвое меньше энергии. Любые идеи относительно того, как я мог бы уменьшить мощность, потребляемую вызовом сна?

К вашему сведению, я использую Ubuntu 3.2.0 на 24-ядерном процессоре Intel Xeon, и поиск частоты в /boot/config показывает следующее:

cat /boot/config-3.2.0-48-generic | egrep 'HZ'
CONFIG_RCU_FAST_NO_HZ=y
CONFIG_NO_HZ=y
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
CONFIG_MACHZ_WDT=m

Однако запуск этого скрипта: http://www.advenage.com/topics/linux-timer-interrupt-frequency.php, я обнаружил, что прерывание таймера ядра составляет не менее 4016 Гц (что в 4 раза превышает частоту, с которой я хотел бы производить выборку). Спасибо за вашу помощь!


person jst14    schedule 17.07.2013    source источник
comment
Пожалуйста, укажите ваше оборудование и какую версию ядра вы используете. Управление состоянием питания — это глубокое вуду и сильно зависит от аппаратного обеспечения.   -  person Andy Ross    schedule 17.07.2013
comment
Марк B (ниже), вероятно, прав, так что это далеко не так, но... Вы можете попробовать использовать timerfd (см. linux.die.net/man/2/timerfd_create), если это проблема с внутренней реализацией nanosleep для небольших интервалов.   -  person Nemo    schedule 17.07.2013
comment
Ubuntu 3.2.0 (как указано выше) и 24-ядерная машина Intel Xeon (теперь добавлена ​​​​в основной корпус)   -  person jst14    schedule 17.07.2013
comment
Что делает sample? Может ли это быть основано на событиях?   -  person Mooing Duck    schedule 17.07.2013
comment
sample фактически измеряет мощность (путем чтения новых счетчиков RAPL от Intel), и я хочу, чтобы измерения мощности были 1/мс, что является частотой обновления счетчика, поэтому я не думаю, что это может быть основано на событиях.   -  person jst14    schedule 17.07.2013


Ответы (1)


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

Я не уверен, что вы можете что-то здесь сделать, хотя потенциально разгон вашего процессора может помочь в энергопотреблении при более частом пробуждении.

person Mark B    schedule 17.07.2013