(Решение в самом низу темы)
Имеется восьмиядерник amd, используется cpufrequtils для реализации функции энергосбережения Q'n'Q для снижения частоты и напряжения в простое. Минимальный интервал обновления устанавливается равным системному интервалу прерываний (у меня 1000Hz) . При запуске задачи частота процессора увеличивается не сразу, а только после определения нагрузки - то есть по видимому через этот интервал, естественно по сравнению с режимом без энергосбережения производительность падает, но проблема не в этом, так как падает не сильно, порядка 5% - но если нагружены практически все ядра, то есть как минимум 6-7 потоков. Проблема возникает когда запущено меньшее количество потоков, особенно если всего один поток - планировщик старается размазать нагрузку по всем ядрам - поток скачет по ядрам - частота каждого ядра увеличивается к тому времени как поток уже собирается ускакать на другое ядро, в итоге этот единственный поток постоянно работает на минимальной частоте - и его производительность падает многократно. Вот это уже проблема. Конечно можно привязывать процессы к ядрам посредством taskset, но это не всегда возможно. Например компиляция в несколько потоков (make -j8) иногда выполняется в одном потоке (например конфигурация или большой прекомпилированный заголовок) и это бутылочное горло становится еще уже. Отключать режим энергосбережения не хочется, потому что иначе за час даже в простое проц поджаривает все вокруг, а так работать тоже не дело.
Linux 3.2.12-gentoo SMP x86_64 AMD FX(tm)-8150 Eight-Core Processor AuthenticAMD GNU/Linux
# cat /etc/conf.d/cpufrequtils
START_OPTS="--governor ondemand"
SYSFS_EXTRA="ondemand/up_threshold=98 ondemand/io_is_busy=1 ondemand/sampling_rate=1"
STOP_OPTS="--governor performance"
Cpufreq и производительность одного потока
Мне непонятно, в чём тут проблема. Если процессор успевает выполнять задачу
без повышения частоты до максимальной, так это только хорошо. Когда задача
является ресурсоёмкой, тогда и ядро будет больше времени работать на максимальной
частоте. Ваша задача просто не загружает процессор. Попробуйте для сравнения
запустить перекодировку видеофайла и загрузка ядра будет 100%.
Пётр.
Задача нагружает ядро на 100%.
Если поток нагружает ядро на 100%, то его частота увеличивается практически мгновенно. Откуда данные, что частота медленно (и на сколько медленно) увеличивается?
Интервал оценки загрузки ядра и смена его частоты:
cat /sys/devices/system/cpu/cpufreq/ondemand/sampling_rate
10000
= 10мс - это минимальное значение равное частоте прерываний в системе
Решение: увеличить sampling_down_factor.
echo -n 10 > /sys/devices/system/cpu/cpufreq/ondemand/sampling_down_factor
sampling_down_factor - это множитель для интервала sampling_rate, в течении которого ядро будет оставаться на повышенной частоте после снятия нагрузки, таким образом если поток скачет по ядрам бывая на каждом ядре чаще чем заданный интервал (sampling_down_factor*sampling_rate), то используемые ядра всегда будут на повышенной частоте, пока нагрузка на процессор не исчезнет.
Более подробно: https://wiki.archlinux.org/index.php/CPU_Frequency_Scaling#On-demand_governor_sampling_down_factor