Исследуя состояния питания процессора Core 2 (« C-состояния »), мне фактически удалось реализовать поддержку большинства устаревших процессоров Intel Core / Core 2. Полная реализация (патч для Linux) со всей исходной информацией описана здесь.
Когда я накопил больше информации об этих процессорах, стало очевидно, что C-состояния, поддерживаемые в модели (ях) Core 2, намного сложнее, чем в более ранних и более поздних процессорах. Они известны как расширенные C-состояния (или « CxE »), которые включают пакет, отдельные ядра и другие компоненты на чипсете (например, память). В то времяintel_idle
был выпущен драйвер, код не был особенно зрелым, и было выпущено несколько процессоров Core 2, которые имели конфликтующую поддержку C-состояний.
Некоторая убедительная информация о поддержке Core 2 Solo / Duo C-state была найдена в этой статье с 2006 года . Это связано с поддержкой в Windows, однако это указывает на надежную аппаратную поддержку C-состояний на этих процессорах. Информация, касающаяся Кентсфилда, противоречит фактическому номеру модели, поэтому я полагаю, что они на самом деле относятся к Yorkfield ниже:
... четырехъядерный процессор Intel Core 2 Extreme (Kentsfield) поддерживает все пять технологий производительности и энергосбережения - расширенный Intel SpeedStep (EIST), Thermal Monitor 1 (TM1) и Thermal Monitor 2 (TM2), старые часы по требованию Модуляция (ODCM), а также расширенные состояния C (CxE). По сравнению с процессорами Intel Pentium 4 и Pentium D 600, 800 и 900, которые характеризуются только состоянием Enhanced Halt (C1), эта функция была расширена в процессорах Intel Core 2 (а также процессорах Intel Core Solo / Duo) для все возможные состояния простоя процессора, включая Стоп-грант (C2), Deep Sleep (C3) и Deeper Sleep (C4).
В этой статье за 2008 год описана поддержка C-состояний для каждого ядра на многоядерных процессорах Intel, включая Core 2 Duo и Core 2 Quad (дополнительные полезные справочные материалы были найдены в этом техническом документе Dell ):
Базовое C-состояние - это аппаратное C-состояние. Существует несколько основных состояний простоя, например, CC1 и CC3. Как мы знаем, современный современный процессор имеет несколько ядер, например недавно выпущенные мобильные процессоры Core Duo T5000 / T7000, известные в некоторых кругах как Penryn. То, что мы привыкли считать процессором / процессором, на самом деле имеет несколько процессоров общего назначения. Intel Core Duo имеет 2 ядра в чипе процессора. Intel Core-2 Quad имеет 4 таких ядра на каждый чип процессора. Каждое из этих ядер имеет свое собственное состояние простоя. Это имеет смысл, поскольку одно ядро может бездействовать, в то время как другое тяжело работает с потоком. Таким образом, состояние C ядра является состоянием бездействия одного из этих ядер.
Я нашел презентацию Intel от 2010 года, в которой содержатся некоторые дополнительные сведения о intel_idle
драйвере, но, к сожалению, не объясняется отсутствие поддержки Core 2:
Этот ЭКСПЕРИМЕНТАЛЬНЫЙ драйвер заменяет acpi_idle на процессорах Intel Atom, процессорах Intel Core i3 / i5 / i7 и связанных процессорах Intel Xeon. Он не поддерживает процессор Intel Core2 или более раннюю версию.
Приведенное выше представление указывает на то, что intel_idle
драйвер является реализацией регулятора ЦП «меню», что влияет на конфигурацию ядра Linux (т. CONFIG_CPU_IDLE_GOV_LADDER
Е. Против CONFIG_CPU_IDLE_GOV_MENU
). Различия между лэддерами и регуляторами меню кратко описаны в этом ответе .
У Dell есть полезная статья, в которой перечислены совместимости C-state C0-C6:
Режимы C1-C3 работают, в основном, обрезая тактовые сигналы, используемые внутри ЦП, в то время как режимы C4-C6 работают за счет снижения напряжения ЦП. «Расширенные» режимы могут выполнять оба режима одновременно.
Mode Name CPUs
C0 Operating State All CPUs
C1 Halt 486DX4 and above
C1E Enhanced Halt All socket LGA775 CPUs
C1E — Turion 64, 65-nm Athlon X2 and Phenom CPUs
C2 Stop Grant 486DX4 and above
C2 Stop Clock Only 486DX4, Pentium, Pentium MMX, K5, K6, K6-2, K6-III
C2E Extended Stop Grant Core 2 Duo and above (Intel only)
C3 Sleep Pentium II, Athlon and above, but not on Core 2 Duo E4000 and E6000
C3 Deep Sleep Pentium II and above, but not on Core 2 Duo E4000 and E6000; Turion 64
C3 AltVID AMD Turion 64
C4 Deeper Sleep Pentium M and above, but not on Core 2 Duo E4000 and E6000 series; AMD Turion 64
C4E/C5 Enhanced Deeper Sleep Core Solo, Core Duo and 45-nm mobile Core 2 Duo only
C6 Deep Power Down 45-nm mobile Core 2 Duo only
Из этой таблицы (которую я позже обнаружил, что в некоторых случаях она неверна) видно, что в поддержке C-состояний с процессорами Core 2 было множество различий (обратите внимание, что почти все процессоры Core 2 являются Socket LGA775, за исключением Core 2 Solo SU3500, который представляет собой процессоры Socket BGA956 и Merom / Penryn. «Intel Core» Процессоры Solo / Duo относятся к Socket PBGA479 или PPGA478).
В этой статье было найдено дополнительное исключение к таблице :
Intel Core 2 Duo E8500 поддерживает C-состояния C2 и C4, а Core 2 Extreme QX9650 - нет.
Интересно, что QX9650 представляет собой процессор Yorkfield (семейство Intel 6, модель 23, степпинг 6). Для справки, мой Q9550S - это семейство Intel 6, модель 23 (0x17), шаг 10, который предположительно поддерживает C-состояние C4 (подтверждено экспериментально). Кроме того, Core 2 Solo U3500 имеет идентификатор CPUID (семейство, модель, степпинг), идентичный Q9550S, но доступен в разъеме, отличном от LGA775, что затрудняет интерпретацию приведенной выше таблицы.
Ясно, что CPUID должен использоваться, по крайней мере, до шага, чтобы определить поддержку C-состояний для этой модели процессора, а в некоторых случаях этого может быть недостаточно (в настоящее время не определено).
Сигнатура метода для назначения информации о простое ЦП:
#define ICPU(model, cpu) \
{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&cpu }
Где model
перечислено в asm / intel-family.h . Изучая этот заголовочный файл, я вижу, что процессорам Intel назначаются 8-разрядные идентификаторы, которые соответствуют номерам моделей семейства Intel 6:
#define INTEL_FAM6_CORE2_PENRYN 0x17
Исходя из вышеизложенного, мы имеем Intel Family 6, модель 23 (0x17), определенную как INTEL_FAM6_CORE2_PENRYN
. Этого должно быть достаточно для определения незанятых состояний для большинства процессоров модели 23, но потенциально может вызвать проблемы с QX9650, как отмечено выше.
Таким образом, как минимум, каждая группа процессоров, которая имеет отдельный набор состояний C, должна быть определена в этом списке.
Zagacki and Ponnala, Intel Technology Journal 12 (3): 219-227, 2008, указывают, что процессоры Yorkfield действительно поддерживают C2 и C4. Кажется, они также указывают на то, что спецификация ACPI 3.0a поддерживает переходы только между C-состояниями C0, C1, C2 и C3, что, как я полагаю, может также ограничить acpi_idle
драйвер Linux переходами между этим ограниченным набором C-состояний. Тем не менее, эта статья указывает, что не всегда так:
Имейте в виду, что это состояние ACPI C, а не процессорное, поэтому ACPI C3 может быть HW C6 и т. Д.
Также примечание:
Помимо самого процессора, поскольку C4 является синхронизированным усилием между основными кремниевыми компонентами платформы, набор микросхем Intel Q45 Express обеспечивает повышение энергопотребления на 28 процентов.
Чипсет, который я использую, действительно является набором микросхем Intel Q45 Express.
Документация Intel о состояниях MWAIT является краткой, но подтверждает поведение ACPI, специфичное для BIOS:
Специфичные для процессора C-состояния, определенные в расширениях MWAIT, могут отображаться в ACPI-определенные типы C-состояний (C0, C1, C2, C3). Отношение сопоставления зависит от определения состояния C для реализации процессора и предоставляется OSPM BIOS с использованием таблицы _CST, определенной ACPI.
Моя интерпретация приведенной выше таблицы (в сочетании с таблицей из Википедии , asm / intel-family.h и приведенными выше статьями) такова:
Модель 9 0x09 ( Pentium M и Celeron M ):
- Баниас: C0, C1, C2, C3, C4
Модель 13 0x0D ( Pentium M и Celeron M ):
- Дотан, Стили: C0, C1, C2, C3, C4
Модель 14 0x0E INTEL_FAM6_CORE_YONAH ( усовершенствованный Pentium M , усовершенствованный Celeron M или Intel Core ):
- Йона ( Core Solo , Core Duo ): C0, C1, C2, C3, C4, C4E / C5
Модель 15 0x0F INTEL_FAM6_CORE2_MEROM (некоторые Core 2 и Pentium Dual-Core ):
- Kentsfield, Merom, Conroe, Allendale ( E2xxx / E4xxx и Core 2 Duo E6xxx, T7xxxx / T8xxxx , Core 2 Extreme QX6xxx , Core 2 Quad Q6xxx ): C0, C1, C1E, C2, C2E
Модель 23 0x17 INTEL_FAM6_CORE2_PENRYN ( ядро 2 ):
- Мером-Л / Пенрин-Л:?
- Penryn ( Core 2 Duo 45-нм мобильный ): C0, C1, C1E, C2, C2E, C3, C4, C4E / C5, C6
- Yorkfield ( Core 2 Extreme QX9650 ): C0, C1, C1E, C2E ?, C3
- Wolfdale / Yorkfield ( Core 2 Quad , C2Q Xeon , Core 2 Duo E5xxx / E7xxx / E8xxx , Pentium Двухъядерный E6xxx , Celeron Dual-Core ): C0, C1, C1E, C2, C2E, C3, C4
Из различий в поддержке C-состояний только в линейке процессоров Core 2 видно, что отсутствие последовательной поддержки C-состояний могло быть причиной того, что они не пытались полностью поддерживать их через intel_idle
драйвер. Я хотел бы полностью завершить приведенный выше список для всей линии Core 2.
Это не совсем удовлетворительный ответ, потому что это заставляет меня задуматься о том, сколько ненужной энергии используется и избыточное тепло генерируется (и остается) из-за неполного использования надежных энергосберегающих состояний MWAIT C на этих процессорах.
Chattopadhyay et al. 2018, Энергоэффективные высокопроизводительные процессоры: последние подходы к проектированию «зеленых» высокопроизводительных вычислений , стоит отметить особенное поведение, которое я ищу в наборе микросхем Q45 Express:
Состояние C пакета (PC0-PC10) - когда вычислительные домены, ядро и графика (GPU) простаивают, процессор имеет возможность для дополнительной экономии энергии на уровне ядра и платформы, например, сбрасывая LLC и запуская питание контроллер памяти и DRAM IO, а в каком-то состоянии весь процессор может быть отключен, в то время как его состояние сохраняется в постоянно включенной области питания.
В качестве теста я вставил следующее в строку linux / drivers / idle / intel_idle.c 127:
static struct cpuidle_state conroe_cstates[] = {
{
.name = "C1",
.desc = "MWAIT 0x00",
.flags = MWAIT2flg(0x00),
.exit_latency = 3,
.target_residency = 6,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
{
.name = "C1E",
.desc = "MWAIT 0x01",
.flags = MWAIT2flg(0x01),
.exit_latency = 10,
.target_residency = 20,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
// {
// .name = "C2",
// .desc = "MWAIT 0x10",
// .flags = MWAIT2flg(0x10),
// .exit_latency = 20,
// .target_residency = 40,
// .enter = &intel_idle,
// .enter_s2idle = intel_idle_s2idle, },
{
.name = "C2E",
.desc = "MWAIT 0x11",
.flags = MWAIT2flg(0x11),
.exit_latency = 40,
.target_residency = 100,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
{
.enter = NULL }
};
static struct cpuidle_state core2_cstates[] = {
{
.name = "C1",
.desc = "MWAIT 0x00",
.flags = MWAIT2flg(0x00),
.exit_latency = 3,
.target_residency = 6,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
{
.name = "C1E",
.desc = "MWAIT 0x01",
.flags = MWAIT2flg(0x01),
.exit_latency = 10,
.target_residency = 20,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
{
.name = "C2",
.desc = "MWAIT 0x10",
.flags = MWAIT2flg(0x10),
.exit_latency = 20,
.target_residency = 40,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
{
.name = "C2E",
.desc = "MWAIT 0x11",
.flags = MWAIT2flg(0x11),
.exit_latency = 40,
.target_residency = 100,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
{
.name = "C3",
.desc = "MWAIT 0x20",
.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 85,
.target_residency = 200,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
{
.name = "C4",
.desc = "MWAIT 0x30",
.flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 100,
.target_residency = 400,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
{
.name = "C4E",
.desc = "MWAIT 0x31",
.flags = MWAIT2flg(0x31) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 100,
.target_residency = 400,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
{
.name = "C6",
.desc = "MWAIT 0x40",
.flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 200,
.target_residency = 800,
.enter = &intel_idle,
.enter_s2idle = intel_idle_s2idle, },
{
.enter = NULL }
};
в intel_idle.c
строке 983:
static const struct idle_cpu idle_cpu_conroe = {
.state_table = conroe_cstates,
.disable_promotion_to_c1e = false,
};
static const struct idle_cpu idle_cpu_core2 = {
.state_table = core2_cstates,
.disable_promotion_to_c1e = false,
};
в intel_idle.c
строке 1073:
ICPU(INTEL_FAM6_CORE2_MEROM, idle_cpu_conroe),
ICPU(INTEL_FAM6_CORE2_PENRYN, idle_cpu_core2),
После быстрой компиляции и перезагрузки моих узлов PXE dmesg
теперь показано:
[ 0.019845] cpuidle: using governor menu
[ 0.515785] clocksource: acpi_pm: mask: 0xffffff max_cycles: 0xffffff, max_idle_ns: 2085701024 ns
[ 0.543404] intel_idle: MWAIT substates: 0x22220
[ 0.543405] intel_idle: v0.4.1 model 0x17
[ 0.543413] tsc: Marking TSC unstable due to TSC halts in idle states deeper than C2
[ 0.543680] intel_idle: lapic_timer_reliable_states 0x2
И теперь PowerTOP показывает:
Package | CPU 0
POLL 2.5% | POLL 0.0% 0.0 ms
C1E 2.9% | C1E 5.0% 22.4 ms
C2 0.4% | C2 0.2% 0.2 ms
C3 2.1% | C3 1.9% 0.5 ms
C4E 89.9% | C4E 92.6% 66.5 ms
| CPU 1
| POLL 10.0% 400.8 ms
| C1E 5.1% 6.4 ms
| C2 0.3% 0.1 ms
| C3 1.4% 0.6 ms
| C4E 76.8% 73.6 ms
| CPU 2
| POLL 0.0% 0.2 ms
| C1E 1.1% 3.7 ms
| C2 0.2% 0.2 ms
| C3 3.9% 1.3 ms
| C4E 93.1% 26.4 ms
| CPU 3
| POLL 0.0% 0.7 ms
| C1E 0.3% 0.3 ms
| C2 1.1% 0.4 ms
| C3 1.1% 0.5 ms
| C4E 97.0% 45.2 ms
Я наконец-то получил доступ к C-состояниям Enhanced Core 2, и похоже, что измеримое снижение энергопотребления - мой индикатор на 8 узлах в среднем как минимум на 5% ниже (при этом один узел все еще работает со старым ядром) , но я попробую поменять ядра снова как тест.
Интересное замечание относительно поддержки C4E - процессор My Yorktown Q9550S, кажется, поддерживает его (или некоторое другое подсостояние C4), как показано выше! Это сбивает меня с толку, потому что в спецификации Intel на процессоре Core 2 Q9000 (раздел 6.2) упоминаются только C-состояния Normal (C0), HALT (C1 = 0x00), Extended HALT (C1E = 0x01), Stop Grant (C2 = 0x10) , Расширенный Стоп-грант (C2E = 0x11), Сон / Глубокий сон (C3 = 0x20) и Глубокий сон (C4 = 0x30). Что это за дополнительное состояние 0x31? Если я включаю состояние C2, то вместо C4 используется C4E. Если я отключаю состояние C2 (форсированное состояние C2E), то вместо C4E используется C4. Я подозреваю, что это может быть как-то связано с флагами MWAIT, но я еще не нашел документацию по этому поведению.
Я не уверен, что делать с этим: состояние C1E, кажется, используется вместо C1, C2 используется вместо C2E, а C4E используется вместо C4. Я не уверен, могут ли C1 / C1E, C2 / C2E и C4 / C4E использоваться вместе с ними intel_idle
или они являются избыточными. В этой презентации Intel Labs Pittsburgh 2010 года я обнаружил примечание, в котором указано, что переходы - это C0 - C1 - C0 - C1E - C0, а также следующие состояния:
C1E используется только тогда, когда все ядра находятся в C1E
Я полагаю, что это следует интерпретировать как состояние C1E, которое вводится на других компонентах (например, в памяти), только когда все ядра находятся в состоянии C1E. Я также полагаю, что это применимо эквивалентно к состояниям C2 / C2E и C4 / C4E (хотя C4E упоминается как «C4E / C5», поэтому я не уверен, является ли C4E подсостоянием C4 или C5 является подсостоянием состояние C4E. Тестирование показывает, что C4 / C4E верный). Я могу заставить C2E использоваться, закомментировав состояние C2 - однако, это заставляет использовать состояние C4 вместо C4E (здесь может потребоваться дополнительная работа). Надеемся, что нет процессоров моделей 15 или 23, в которых отсутствует состояние C2E, потому что эти процессоры будут ограничены C1 / C1E с приведенным выше кодом.
Кроме того, значения флагов, задержек и резидентности, вероятно, могли бы быть точно настроены, но, похоже, что просто взятие образованных догадок на основе значений ожидания Nehalem работает нормально. Чтобы сделать какие-либо улучшения, потребуется больше чтения.
Я тестировал это на Core 2 Duo E2220 ( Allendale ), двухъядерном Pentium E5300 ( Wolfdale ), Core 2 Duo E7400 , Core 2 Duo E8400 ( Wolfdale ), Core 2 Quad Q9550S ( Yorkfield ) и Core 2 Extreme QX9650 , и я не нашли никаких проблем, кроме вышеупомянутого предпочтения для состояний C2 / C2E и C4 / C4E.
Не распространяется на эту модификацию драйвера:
- Оригинальные Core Solo / Core Duo ( Yonah , не Core 2) относятся к семейству 6, модели 14. Это хорошо, потому что они поддерживали C-состояния C4E / C5 (Enhanced Deep Sleep), но не состояния C1E / C2E, и им потребуются их собственное простое определение.
Единственные проблемы, о которых я могу думать:
- Core 2 Solo SU3300 / SU3500 (Penryn-L) относятся к семейству 6, модели 23 и будут обнаружены этим драйвером. Однако это не Socket LGA775, поэтому они могут не поддерживать C-состояние расширенной остановки C1E. Аналогично для Core 2 Solo ULV U2100 / U2200 ( Merom-L ). Однако
intel_idle
драйвер, по-видимому, выбирает соответствующий C1 / C1E на основе аппаратной поддержки подсостояний.
- Core 2 Extreme QX9650 (Yorkfield) по сообщениям не поддерживает C-состояние C2 или C4. Я подтвердил это, купив на eBay использованный процессор Optiplex 780 и QX9650 Extreme. Процессор поддерживает C-состояния C1 и C1E. С этой модификацией драйвера процессор работает в состоянии C1E вместо C1, поэтому, возможно, имеется некоторая экономия энергии. Я ожидал увидеть C-состояние C3, но его нет при использовании этого драйвера, поэтому мне, возможно, придется изучить это подробнее.
Мне удалось найти слайд из презентации Intel 2009 года о переходах между состояниями C (т. Е. Deep Power Down):
В заключение получается, что не было реальной причины отсутствия поддержки Core 2 в intel_idle
драйвере. Теперь ясно, что исходный код заглушки для «Core 2 Duo» обрабатывал только C-состояния C1 и C2, что было бы гораздо менее эффективным, чем acpi_idle
функция, которая также обрабатывает C-состояние C3. Когда я знал, где искать, реализовать поддержку было легко. Полезные комментарии и другие ответы были высоко оценены, и если Amazon слушает, вы знаете, куда отправить чек.
Это обновление было передано на github . Я скоро отправлю патч в LKML.
Обновление : мне также удалось выкопать Socket T / LGA775 Allendale ( Conroe ) Core 2 Duo E2220, который является семейством 6, модель 15, поэтому я также добавил поддержку для этого. В этой модели отсутствует поддержка C-состояния C4, но поддерживается C1 / C1E и C2 / C2E. Это также должно работать на других чипах на основе Conroe ( E4xxx / E6xxx ) и, возможно, на всех процессорах Kentsfield и Merom (не Merom-L).
Обновление : я наконец нашел некоторые ресурсы настройки MWAIT. Эти записи о производительности и производительности, а также о более глубоких состояниях C и публикации в блоге с увеличенной задержкой содержат полезную информацию по определению задержек простоя ЦП. К сожалению, это сообщает только о тех задержках выхода, которые были закодированы в ядре (но, что интересно, только те аппаратные состояния, которые поддерживаются процессором):
# cd /sys/devices/system/cpu/cpu0/cpuidle
# for state in `ls -d state*` ; do echo c-$state `cat $state/name` `cat $state/latency` ; done
c-state0/ POLL 0
c-state1/ C1 3
c-state2/ C1E 10
c-state3/ C2 20
c-state4/ C2E 40
c-state5/ C3 20
c-state6/ C4 60
c-state7/ C4E 100
acpi_idle
различные регуляторы производительности. Какие состоянияpowertop
отображаются в вашей системе?