เหตุใด Intel รุ่น 6 ตระกูลบางรุ่น (Core 2, Pentium M) จึงไม่รองรับโดย intel_idle


25

ฉันได้ปรับเคอร์เนล Linux สำหรับโปรเซสเซอร์ Intel Core 2 Quad (Yorkfield) และฉันสังเกตเห็นข้อความต่อไปนี้จากdmesg:

[    0.019526] cpuidle: using governor menu
[    0.531691] clocksource: acpi_pm: mask: 0xffffff max_cycles: 0xffffff, max_idle_ns: 2085701024 ns
[    0.550918] intel_idle: does not run on family 6 model 23
[    0.554415] tsc: Marking TSC unstable due to TSC halts in idle

PowerTop แสดงเฉพาะสถานะ C1, C2 และ C3 ที่ใช้สำหรับแพ็คเกจและแต่ละคอร์:

          Package   |            CPU 0
POLL        0.0%    | POLL        0.0%    0.1 ms
C1          0.0%    | C1          0.0%    0.0 ms
C2          8.2%    | C2          9.9%    0.4 ms
C3         84.9%    | C3         82.5%    0.9 ms

                    |            CPU 1
                    | POLL        0.1%    1.6 ms
                    | C1          0.0%    1.5 ms
                    | C2          9.6%    0.4 ms
                    | C3         82.7%    1.0 ms

                    |            CPU 2
                    | POLL        0.0%    0.1 ms
                    | C1          0.0%    0.0 ms
                    | C2          7.2%    0.3 ms
                    | C3         86.5%    1.0 ms

                    |            CPU 3
                    | POLL        0.0%    0.1 ms
                    | C1          0.0%    0.0 ms
                    | C2          5.9%    0.3 ms
                    | C3         87.7%    1.0 ms

อยากรู้อยากเห็นฉันถามsysfsและพบว่าacpi_idleไดรเวอร์เดิมมีการใช้งาน (ฉันคาดว่าจะเห็นintel_idleไดรเวอร์):

cat /sys/devices/system/cpu/cpuidle/current_driver

acpi_idle

ดูที่ซอร์สโค้ดเคอร์เนลไดรเวอร์intel_idleปัจจุบันมีข้อความดีบั๊กโดยเฉพาะเพื่อแจ้งให้ทราบว่าไดรเวอร์บางรุ่นตระกูล Intel 6 ไม่ได้รับการรองรับ:

if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && boot_cpu_data.x86 == 6)
    pr_debug("does not run on family %d model %d\n", boot_cpu_data.x86, boot_cpu_data.x86_model);

fork_id (22 พฤศจิกายน 2010) ก่อนหน้าของintel_idle.cแสดงการสนับสนุนที่คาดไว้สำหรับโปรเซสเซอร์ Core 2 (รุ่น 23 ครอบคลุมทั้ง Core 2 Duo และ Quad จริง ๆ แล้ว):

#ifdef FUTURE_USE
    case 0x17:  /* 23 - Core 2 Duo */
        lapic_timer_reliable_states = (1 << 2) | (1 << 1); /* C2, C1 */
#endif

รหัสดังกล่าวถูกลบออกในเดือนธันวาคม 2010 กระทำ

น่าเสียดายที่ไม่มีเอกสารประกอบในซอร์สโค้ดดังนั้นจึงไม่มีคำอธิบายเกี่ยวกับการขาดการรองรับฟังก์ชั่นที่ไม่ได้ใช้งานใน CPU เหล่านี้

การกำหนดค่าเคอร์เนลปัจจุบันของฉันเป็นดังนี้:

CONFIG_SMP=y
CONFIG_MCORE2=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_ACPI_PROCESSOR_IDLE=y
CONFIG_CPU_IDLE=y
# CONFIG_CPU_IDLE_GOV_LADDER is not set
CONFIG_CPU_IDLE_GOV_MENU=y
# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
CONFIG_INTEL_IDLE=y

คำถามของฉันมีดังนี้:

  • มีเหตุผลฮาร์ดแวร์เฉพาะที่ไม่สนับสนุนโปรเซสเซอร์ Core 2 intel_idleหรือไม่
  • มีวิธีที่เหมาะสมกว่าในการกำหนดค่าเคอร์เนลเพื่อรองรับ CPU idle ที่เหมาะสมที่สุดสำหรับโปรเซสเซอร์ตระกูลนี้intel_idleหรือไม่(นอกเหนือจากการปิดใช้งานการสนับสนุน)

คำตอบ:


28

ในขณะที่กำลังค้นคว้าสถานะพลังงาน CPU Core 2 (" C-state ") ฉันได้รับการจัดการเพื่อสนับสนุนโปรเซสเซอร์ Intel Core / Core 2 ส่วนใหญ่รุ่นเก่า การใช้งานที่สมบูรณ์ (แพทช์ Linux) พร้อมข้อมูลพื้นฐานทั้งหมดได้รับการบันทึกไว้ที่นี่

เมื่อฉันสะสมข้อมูลเพิ่มเติมเกี่ยวกับโปรเซสเซอร์เหล่านี้มันเริ่มเห็นได้ชัดว่า C-state ที่สนับสนุนในรุ่น Core 2 มีความซับซ้อนมากกว่าตัวประมวลผลทั้งก่อนหน้าและหลัง สิ่งเหล่านี้รู้จักกันในชื่อEnhanced C-states (หรือ " CxE ") ซึ่งเกี่ยวข้องกับแพคเกจคอร์แต่ละคอร์และส่วนประกอบอื่น ๆ บนชิปเซ็ต (เช่นหน่วยความจำ) ในขณะที่intel_idleมีการเปิดตัวไดรฟ์เวอร์โค้ดนั้นยังไม่ได้รับการพัฒนาเป็นพิเศษและโปรเซสเซอร์ Core 2 จำนวนมากได้รับการเผยแพร่ซึ่งขัดแย้งกับการสนับสนุนของรัฐซี

บางข้อมูลที่น่าสนใจเกี่ยวกับ Core 2 Solo / Duo C-รัฐสนับสนุนถูกพบในบทความนี้จาก 2006 สิ่งนี้เกี่ยวข้องกับการสนับสนุนบน Windows อย่างไรก็ตามมันบ่งบอกถึงการสนับสนุน C-state ของฮาร์ดแวร์ที่แข็งแกร่งในโปรเซสเซอร์เหล่านี้ ข้อมูลเกี่ยวกับ Kentsfield ขัดแย้งกับหมายเลขรุ่นจริงดังนั้นฉันเชื่อว่าพวกเขาอ้างถึง Yorkfield ด้านล่าง:

... โปรเซสเซอร์ Quad-core Intel Core 2 Extreme (Kentsfield) รองรับทั้งห้าสมรรถนะและเทคโนโลยีประหยัดพลังงาน - Enhanced Intel SpeedStep (EIST), Thermal Monitor 1 (TM1) และ Thermal Monitor 2 (TM2), นาฬิกาตามต้องการ การปรับ (ODCM) รวมถึง Enhanced C States (CxE) เปรียบเทียบกับโปรเซสเซอร์ Intel Pentium 4 และ Pentium D 600, 800 และ 900 ซึ่งโดดเด่นด้วย Enhanced Halt (C1) State เท่านั้นฟังก์ชั่นนี้ได้รับการขยายในโปรเซสเซอร์ Intel Core 2 (รวมถึงโปรเซสเซอร์ Intel Core Solo / Duo) สำหรับ สถานะว่างทั้งหมดของโปรเซสเซอร์รวมถึง Stop Grant (C2), Deep Sleep (C3) และ Deeper Sleep (C4)

บทความนี้จากปี 2008สรุปการสนับสนุนสำหรับ C-state ต่อคอร์ในโปรเซสเซอร์แบบมัลติคอร์ของ Intel รวมถึง Core 2 Duo และ Core 2 Quad (พบการอ่านพื้นหลังที่เป็นประโยชน์เพิ่มเติมในกระดาษสีขาวนี้จาก Dell ):

แกน C-state เป็นฮาร์ดแวร์ C-state มีสถานะไม่ได้ใช้งานหลักหลายสถานะเช่น CC1 และ CC3 ดังที่เราทราบโปรเซสเซอร์ล้ำสมัยมีหลายคอร์เช่นโปรเซสเซอร์มือถือ Core Duo T5000 / T7000 ที่รู้จักกันในชื่อ Penryn ในบางวงการ สิ่งที่เราเคยคิดว่าเป็นซีพียู / โปรเซสเซอร์จริง ๆ แล้วมีซีพียูเอนกประสงค์มากมาย Intel Core Duo มี 2 คอร์ในชิปโปรเซสเซอร์ Intel Core-2 Quad มี 4 คอร์ต่อชิปโปรเซสเซอร์ แต่ละแกนเหล่านี้มีสถานะว่างของตัวเอง เรื่องนี้ทำให้รู้สึกเป็นหนึ่งในแกนกลางอาจไม่ได้ใช้งานในขณะที่อีกคนเป็นงานที่หนักในหัวข้อ ดังนั้นแกน C-state คือสถานะว่างของหนึ่งในคอร์เหล่านั้น

ฉันพบการนำเสนอในปี 2010 จาก Intelที่ให้ข้อมูลเพิ่มเติมเกี่ยวกับintel_idleไดรเวอร์ แต่น่าเสียดายที่ไม่ได้อธิบายถึงการขาดการสนับสนุนสำหรับ Core 2:

โปรแกรมควบคุมการทดลองนี้แทนที่ acpi_idle บนโปรเซสเซอร์ Intel Atom, โปรเซสเซอร์ Intel Core i3 / i5 / i7 และโปรเซสเซอร์ Intel Xeon ที่เกี่ยวข้อง ไม่รองรับโปรเซสเซอร์ Intel Core2 หรือเก่ากว่า

งานนำเสนอข้างต้นไม่ได้ระบุว่าintel_idleไดรเวอร์นั้นมีการใช้งานตัวควบคุมซีพียู "เมนู" ซึ่งมีผลกระทบกับการตั้งค่าเคอร์เนลลินุกซ์ (เช่น, CONFIG_CPU_IDLE_GOV_LADDERvs. CONFIG_CPU_IDLE_GOV_MENU) ความแตกต่างระหว่างบันไดและผู้ว่าราชการเมนูมีคำอธิบายสั้น ๆ ในคำตอบนี้

Dell มีบทความที่มีประโยชน์ซึ่งแสดงรายการความเข้ากันได้ของ C-state C0 ถึง C6:

โหมด C1 ถึง C3 ทำงานโดยการตัดสัญญาณนาฬิกาที่ใช้ภายใน CPU ในขณะที่โหมด C4 ถึง C6 ทำงานโดยลดแรงดันไฟฟ้าของ CPU โหมด "ขั้นสูง" สามารถทำได้ทั้งสองอย่างในเวลาเดียวกัน

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-state กับโปรเซสเซอร์ Core 2 (โปรดทราบว่าโปรเซสเซอร์ Core 2 เกือบทั้งหมดเป็นซ็อกเก็ต LGA775 ยกเว้น Core 2 Solo SU3500 ซึ่งเป็นโปรเซสเซอร์ Socket BGA956 และ Merom / Penryn "Intel Core" โปรเซสเซอร์ Solo / Duo เป็นหนึ่งใน Socket PBGA479 หรือ PPGA478)

พบข้อยกเว้นเพิ่มเติมในตารางในบทความนี้ :

Core 2 Duo E8500 ของ Intel รองรับ C-state C2 และ C4 ในขณะที่ Core 2 Extreme QX9650 ไม่รองรับ

น่าสนใจ QX9650 เป็นโปรเซสเซอร์ Yorkfield (ตระกูล Intel 6 รุ่น 23 ก้าว 6) สำหรับการอ้างอิง Q9550S ​​ของฉันคือตระกูล Intel 6 รุ่น 23 (0x17) ก้าวที่ 10 ซึ่งควรสนับสนุน C-state C4 (ยืนยันผ่านการทดลอง) นอกจากนี้ Core 2 Solo U3500 มี CPUID (ตระกูลรุ่นก้าว) ที่เหมือนกันกับ Q9550S ​​แต่มีอยู่ในซ็อกเก็ตที่ไม่ใช่ LGA775 ซึ่ง จำกัด การตีความของตารางข้างต้น

เห็นได้ชัดว่าต้องใช้ CPUID อย่างน้อยที่สุดถึงขั้นตอนเพื่อระบุการรองรับ C-state สำหรับโปรเซสเซอร์รุ่นนี้และในบางกรณีที่อาจไม่เพียงพอ (ไม่ได้ระบุไว้ในขณะนี้)

ลายเซ็นวิธีการสำหรับการกำหนดข้อมูล CPU ที่ไม่ได้ใช้งานคือ:

#define ICPU(model, cpu) \
{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&cpu }

ที่ไหนmodelมีระบุในasm / Intel-family.h จากการตรวจสอบไฟล์ส่วนหัวนี้ฉันเห็นว่า Intel CPU ได้รับการกำหนดตัวระบุ 8 บิตที่ดูเหมือนจะตรงกับหมายเลขรุ่นตระกูล Intel 6:

#define INTEL_FAM6_CORE2_PENRYN 0x17

จากข้างต้นเราได้กำหนดตระกูล Intel 6, รุ่น 23 (0x17) ไว้INTEL_FAM6_CORE2_PENRYNดังนี้ นี่น่าจะเพียงพอสำหรับการกำหนดสถานะว่างสำหรับโปรเซสเซอร์รุ่น 23 ส่วนใหญ่ แต่อาจทำให้เกิดปัญหากับ QX9650 ตามที่ระบุไว้ข้างต้น

ดังนั้นตัวประมวลผลแต่ละกลุ่มที่มีชุด C-state ที่แตกต่างกันจะต้องถูกกำหนดในรายการนี้

Zagacki และ Ponnala, วารสารเทคโนโลยีของ Intel 12 (3): 219-227, 2008ระบุว่าโปรเซสเซอร์ Yorkfield รองรับ C2 และ C4 พวกเขาดูเหมือนจะบ่งชี้ว่าข้อกำหนด ACPI 3.0a รองรับการเปลี่ยนระหว่าง C-state C0, C1, C2 และ C3 เท่านั้นซึ่งฉันเข้าใจว่าอาจ จำกัดacpi_idleไดรเวอร์Linux ให้เปลี่ยนระหว่างชุด C-state ที่ จำกัด อย่างไรก็ตามบทความนี้ระบุว่าอาจไม่เป็นเช่นนั้นเสมอไป:

จำไว้ว่าเป็นสถานะ ACPI C ไม่ใช่ตัวประมวลผลหนึ่งดังนั้น ACPI C3 อาจเป็น HW C6 เป็นต้น

ยังทราบ:

นอกเหนือจากตัวประมวลผลเองเนื่องจาก C4 เป็นความพยายามในการซิงโครไนซ์ระหว่างส่วนประกอบซิลิคอนหลักในแพลตฟอร์มชิปเซ็ต Intel Q45 Express ได้รับการปรับปรุงพลังงาน 28 เปอร์เซ็นต์

ชิปเซ็ตที่ฉันใช้นั้นเป็นชิปเซ็ต Intel Q45 Express

เอกสารอินเทลในรัฐ MWAITคือสั้น แต่ยืนยันพฤติกรรม BIOS ของ ACPI เฉพาะ:

C-state เฉพาะโปรเซสเซอร์ที่กำหนดไว้ในส่วนขยาย MWAIT สามารถแมปกับประเภท C-state ที่กำหนด ACPI (C0, C1, C2, C3) ความสัมพันธ์การแมปขึ้นอยู่กับคำจำกัดความของ C-state โดยการใช้งานตัวประมวลผลและสัมผัสกับ OSPM โดย BIOS โดยใช้ตาราง ACPI ที่กำหนด _CST

การตีความของฉันของตารางด้านบน (รวมกับตารางจาก Wikipedia , asm / intel-family.hและบทความด้านบน) คือ:

รุ่น 9 0x09 ( Pentium MและCeleron M ):

  • บานิอัส: C0, C1, C2, C3, C4

รุ่น 13 0x0D ( Pentium MและCeleron M ):

  • Dothan, Stealey: C0, C1, C2, C3, C4

รุ่น 14 0x0E INTEL_FAM6_CORE_YONAH ( Enhanced Pentium M , Enhanced Celeron MหรือIntel Core ):

  • Yonah ( 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 ( Core 2 ):

  • Merom-L / Penryn-L:
  • Penryn ( Core 2 Duo 45-nm mobile ): C0, C1, C1E, C2, C2E, C3, C4, C4E / C5, C6
  • Yorkfield ( Core 2 Extreme QX9650 ): C0, C1, C1E, C2E ?, C3
  • Wolfdale / Yorkfield ( คอร์ 2 Quad , C2Q Xeon , Core 2 Duo E5xxx / E7xxx / E8xxx , Pentium Dual-Core E6xxx , Celeron Dual-Core ): C0, C1, C1E, C2, C2E, C3, C4

จากปริมาณความหลากหลายในการสนับสนุน C-state ภายในโปรเซสเซอร์ Core 2 ดูเหมือนว่าการขาดการสนับสนุนที่สอดคล้องกันสำหรับ C-state อาจเป็นสาเหตุของการไม่พยายามสนับสนุนพวกเขาอย่างเต็มที่ผ่านทางintel_idleไดรเวอร์ ฉันต้องการทำรายการด้านบนให้ครบถ้วนสำหรับ Core 2 ทั้งหมด

นี้ไม่ได้จริงๆคำตอบที่น่าพอใจเพราะมันทำให้ฉันสงสัยว่าพลังงานที่ไม่จำเป็นและใช้ความร้อนส่วนเกินที่ได้รับ (และยังเป็น) สร้างโดยไม่ได้อย่างเต็มที่ใช้ที่มีประสิทธิภาพการประหยัดพลังงานMWAIT C-รัฐในโปรเซสเซอร์เหล่านี้

Chattopadhyay และคณะ ปี 2018 โปรเซสเซอร์ประสิทธิภาพสูงประหยัดพลังงาน: แนวทางล่าสุดสำหรับการออกแบบคอมพิวเตอร์ประสิทธิภาพสูงสีเขียวเป็นสิ่งที่ควรค่าสำหรับพฤติกรรมเฉพาะที่ฉันกำลังมองหาในชิปเซ็ต Q45 Express:

แพคเกจ C-state (PC0-PC10) - เมื่อโดเมนการคำนวณ Core และกราฟิก (GPU) ไม่ได้ใช้งานโปรเซสเซอร์จะมีโอกาสสำหรับการประหยัดพลังงานเพิ่มเติมในระดับ uncore และระดับแพลตฟอร์มเช่นการล้าง LLC และ power-gating ตัวควบคุมหน่วยความจำและ 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บรรทัด 1,073:

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

ในที่สุดฉันก็เข้าสู่ Enhanced Core 2 C-state และดูเหมือนว่ามีการใช้พลังงานลดลง - เครื่องวัดของฉันบน 8 โหนดดูเหมือนจะเฉลี่ยอย่างน้อย 5% ต่ำกว่า (โดยมีหนึ่งโหนดที่ยังคงใช้เคอร์เนลเก่า) แต่ฉันจะลองเปลี่ยนเมล็ดใหม่อีกครั้งเพื่อทดสอบ

หมายเหตุที่น่าสนใจเกี่ยวกับการสนับสนุน C4E - โปรเซสเซอร์ Yorktown Q9550S ​​ของฉันดูเหมือนจะสนับสนุน (หรือสถานะย่อยอื่น ๆ ของ C4) ตามที่ปรากฏด้านบน! สิ่งนี้ทำให้ฉันสับสนเพราะแผ่นข้อมูลของ Intel ในโปรเซสเซอร์ Core 2 Q9000 (ส่วนที่ 6.2) ระบุถึง C-state ปกติ (C0), HALT (C1 = 0x00), ขยาย HALT (C1E = 0x01), หยุดให้สิทธิ์ (C2 = 0x10) , Extended Stop Grant (C2E = 0x11), Sleep / Deep Sleep (C3 = 0x20) และ Deeper Sleep (C4 = 0x30) สถานะ 0x31 เพิ่มเติมนี้คืออะไร หากฉันเปิดใช้งานสถานะ C2 ดังนั้น C4E จะถูกใช้แทน C4 ถ้าฉันปิดใช้งานสถานะ C2 (บังคับสถานะ C2E) ดังนั้น C4 จะถูกใช้แทน C4E ฉันสงสัยว่าอาจมีบางอย่างเกี่ยวข้องกับการตั้งค่าสถานะ MWAIT แต่ฉันยังไม่พบเอกสารสำหรับพฤติกรรมนี้

ฉันไม่แน่ใจว่าจะทำสิ่งนี้ได้อย่างไร: สถานะ C1E นั้นถูกใช้แทน C1, C2 ถูกใช้แทน C2E และ C4E ถูกใช้แทน C4 ฉันไม่แน่ใจว่าสามารถใช้ C1 / C1E, C2 / C2E และ C4 / C4E ร่วมกับintel_idleหรือซ้ำซ้อนได้หรือไม่ ฉันพบบันทึกย่อในงานนำเสนอ 2010 โดย Intel Labs Pittsburghที่ระบุว่าช่วงการเปลี่ยนภาพเป็น C0 - C1 - C0 - C1E - C0 และสถานะอื่น ๆ :

C1E ใช้เฉพาะเมื่อแกนทั้งหมดอยู่ใน C1E

ฉันเชื่อว่าจะต้องตีความเมื่อมีการป้อนสถานะ C1E บนส่วนประกอบอื่น ๆ (เช่นหน่วยความจำ) เฉพาะเมื่อคอร์ทั้งหมดอยู่ในสถานะ C1E ฉันยังใช้สิ่งนี้เพื่อนำไปใช้อย่างเท่าเทียมกันกับรัฐ C2 / C2E และ C4 / C4E (แม้ว่า C4E จะเรียกว่า "C4E / C5" ดังนั้นฉันจึงไม่แน่ใจว่า C4E เป็นสถานะย่อยของ C4 หรือถ้า C5 เป็น sub- สถานะของ C4E ดูเหมือนว่าการทดสอบจะระบุว่า C4 / C4E ถูกต้อง) ฉันสามารถบังคับให้ใช้ C2E ได้โดยการใส่ความคิดเห็นของรัฐ C2 - อย่างไรก็ตามสิ่งนี้ทำให้รัฐ C4 ถูกนำมาใช้แทน C4E (อาจต้องใช้งานมากขึ้นที่นี่) หวังว่าจะไม่มีโปรเซสเซอร์รุ่น 15 หรือรุ่น 23 ที่ไม่มีสถานะ C2E เนื่องจากโปรเซสเซอร์เหล่านั้นจะถูก จำกัด ที่ C1 / C1E ด้วยรหัสข้างต้น

ยิ่งไปกว่านั้นค่าสถานะเวลาแฝงและถิ่นที่อยู่อาจปรับให้เข้ากับความละเอียดได้ แต่เพียงแค่ทำการเดาการศึกษาตามค่าที่ไม่ได้ใช้งานของ Nehalem ดูเหมือนจะทำงานได้ดี การอ่านเพิ่มเติมจะต้องทำการปรับปรุงใด ๆ

ฉันทดสอบบนCore 2 Duo E2220 ( Allendale ), Dual Core 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 นี่เป็นสิ่งที่ดีเพราะพวกเขารองรับ C4E / C5 (Enhanced Deep Sleep) C-state แต่ไม่ใช่รัฐ C1E / C2E และพวกเขาต้องการ นิยามที่ไม่ได้ใช้งานของตัวเอง

ปัญหาเดียวที่ฉันคิดได้คือ:

  • Core 2 Solo SU3300 / SU3500 (Penryn-L) คือตระกูล 6 รุ่น 23 และไดรเวอร์นี้จะตรวจพบ อย่างไรก็ตามมันไม่ใช่ Socket LGA775 ดังนั้นจึงอาจไม่รองรับ C1E Enhanced Halt C-state เช่นเดียวกันสำหรับ Core 2 Solo ULV U2100 / U2200 ( Merom-L ) อย่างไรก็ตามintel_idleไดรเวอร์ปรากฏขึ้นเพื่อเลือก C1 / C1E ที่เหมาะสมตามการสนับสนุนฮาร์ดแวร์ของสถานะย่อย
  • Core 2 Extreme QX9650 (Yorkfield) รายงานว่าไม่รองรับ C-state C2 หรือ C4 ฉันได้รับการยืนยันโดยการซื้อ Optiplex 780 และ QX9650 Extreme processor ที่ใช้แล้วบน eBay โปรเซสเซอร์รองรับ C-state C1 และ C1E ด้วยการปรับเปลี่ยนไดรเวอร์นี้ CPU ไม่ทำงานในสถานะ C1E แทนที่จะเป็น C1 ดังนั้นจึงประหยัดพลังงานได้บ้าง ฉันคาดว่าจะเห็น C-state C3 แต่ไม่มีอยู่เมื่อใช้ไดรเวอร์นี้ดังนั้นฉันอาจต้องดูเพิ่มเติมนี้

ฉันจัดการเพื่อหาภาพนิ่งจากการนำเสนอ Intel 2009 ในการเปลี่ยนระหว่าง C-state (เช่น Deep Power Down):

การเข้า / ออกจากเทคโนโลยี Deep Power Down

สรุปแล้วปรากฎว่าไม่มีเหตุผลจริงสำหรับการขาดการสนับสนุน Core 2 ในintel_idleไดรเวอร์ เป็นที่ชัดเจนแล้วในตอนนี้ว่าโค้ด stub ดั้งเดิมของ "Core 2 Duo" นั้นจัดการกับ C-state C1 และ C2 เท่านั้นซึ่งจะมีประสิทธิภาพน้อยกว่าacpi_idleฟังก์ชั่นที่จัดการ C-state C3 ด้วย เมื่อฉันรู้ว่าต้องมองหาสถานที่การใช้งานการสนับสนุนเป็นเรื่องง่าย ความคิดเห็นที่เป็นประโยชน์และคำตอบอื่น ๆ ได้รับการชื่นชมอย่างมากและหาก Amazon กำลังฟังอยู่คุณจะรู้ว่าจะส่งเช็คไปที่ใด

การปรับปรุงนี้ได้รับการมุ่งมั่นที่จะ GitHub ฉันจะส่ง patch ไปที่ LKML ทางอีเมลเร็ว ๆ นี้

อัปเดต : ฉันจัดการขุด Socket T / LGA775 Allendale ( Conroe ) Core 2 Duo E2220 ซึ่งเป็นตระกูล 6 รุ่น 15 ดังนั้นฉันจึงเพิ่มการสนับสนุนเช่นกัน รุ่นนี้ขาดการสนับสนุนสำหรับ C-state C4 แต่รองรับ C1 / C1E และ C2 / C2E สิ่งนี้ควรทำงานกับชิป Conroe อื่น ๆ ( E4xxx / E6xxx ) และโปรเซสเซอร์ Kentsfield และ Merom (ไม่ใช่ Merom-L) ทั้งหมด

อัปเดต : ในที่สุดฉันก็พบทรัพยากรการปรับแต่ง MWAIT บางอย่าง นี้เพาเวอร์สมรรถนะเทียบกับเขียนขึ้นและC ลึกรัฐและเพิ่มขึ้นแฝงบล็อกโพสต์ทั้งสองมีข้อมูลที่เป็นประโยชน์บางอย่างเกี่ยวกับการระบุ CPU ศักยภาพไม่ได้ใช้งาน น่าเสียดายที่นี่รายงานเฉพาะเวลาในการออกจากเวลาที่เข้ารหัสไว้ในเคอร์เนล (แต่น่าสนใจเฉพาะสถานะฮาร์ดแวร์ที่โปรเซสเซอร์สนับสนุนเท่านั้น):

# 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

4
นั่นเป็นงานนักสืบที่ดี! ฉันลืมว่า C-state ของ C2D / C2Q นั้นซับซ้อนเพียงใด การประหยัดพลังงานที่ไม่ได้ใช้ซ้ำหากเฟิร์มแวร์ของคุณดีพอคุณก็ควรได้รับประโยชน์จากสถานะ C บางอย่างผ่านทาง acpi_idleและผู้ควบคุมประสิทธิภาพต่างๆ สถานะใดที่powertopแสดงบนระบบของคุณ
Stephen Kitt

1
ข้อมูลที่ดีมากคุณได้พิจารณาเสนอแพทช์ของคุณกับเคอร์เนล upstream หรือไม่?
Lekensteyn

1
"สถานะ C1E นั้นถูกใช้แทน C1 ... " จะใช้สถานะใด - ตามที่แสดงโดย powertop - ถูกกำหนดโดยเคอร์เนลเท่านั้นดังนั้นฉันเชื่อว่ามันจะไม่ "เกี่ยวข้องกับธง MWAIT" มันจะถูกเลือกขึ้นอยู่กับคำสั่งของรัฐและ exit_latency และ target_residency ที่กล่าวว่าฉันจะกังวลเล็กน้อยเกี่ยวกับสถานะการออกในตารางหากดูเหมือนว่าพวกเขาจะไม่ได้ใช้เมื่อทดสอบ ... ในกรณีที่รัฐเหล่านั้นไม่ทำงานตามที่คาดไว้จริงและมีรูปแบบภาระงานอื่น ๆ ที่นำไปสู่ พวกเขาถูกใช้งานและพฤติกรรมที่ไม่คาดคิดเกิดขึ้น
sourcejedi

1
"ช่วงการเปลี่ยนภาพเป็น C0 - C1 - C0 - C1E - C0" - ฉันไม่คิดว่านั่นเป็นคำอธิบายที่ดีของสไลด์นั้น จากเคอร์เนล / powertopมุมมองการเปลี่ยนแปลงทั้งหมดมาจาก C0 หรือ C0 หากคุณไม่ได้อยู่ใน C0 คุณไม่ได้ใช้งานคำแนะนำใด ๆ ดังนั้นเคอร์เนลจึงไม่สามารถสังเกตหรือร้องขอการเปลี่ยนระหว่างสถานะใด ๆ ใน cpu :-) และอย่างที่คุณพูดผู้ว่าการเคอร์เนล "เมนู" อาจจะดีเช่นกระโดดเข้าสู่ C1E โดยไม่ต้องเสียเวลาใน C1 ก่อน
sourcejedi

1
"เพียงแค่การคาดเดาการศึกษาบนพื้นฐานของค่าไม่ได้ใช้งาน Nehalem ดูเหมือนว่าจะปรับการทำงาน" - บันทึกนี้ไม่ได้เป็นวิธีที่ดีที่จะได้รับแพทช์ของคุณได้รับการยอมรับ :-P ต้นน้ำในการที่แฝงทางออกจะต้องไม่เป็นผู้ประมาทมิฉะนั้นผมคิดว่าคุณจะ ละเมิด PM_QOS_CPU_DMA_LATENCY ซึ่งอาจถูกกำหนดโดยไดรเวอร์ (หรือ userspace?)
sourcejedi

6

ฉันสงสัยว่านี่อาจเป็นกรณีของโอกาสและค่าใช้จ่าย เมื่อintel_idleมีการเพิ่มเข้ามาดูเหมือนว่าจะมีการวางแผนสนับสนุน Core 2 Duo แต่ก็ไม่เคยมีการใช้งานอย่างเต็มที่ - บางทีในช่วงที่วิศวกรของ Intel เข้ามาถึงมันก็ไม่คุ้มกับมันอีกแล้ว สมการค่อนข้างซับซ้อน: intel_idleจำเป็นต้องให้ผลประโยชน์ที่เพียงพอacpi_idleเพื่อให้คุ้มค่ากับการสนับสนุนที่นี่บน CPUs ซึ่งจะเห็นเคอร์เนล "ปรับปรุง" ในจำนวนที่เพียงพอ ...

ตามคำตอบของsourcejediกล่าวว่าคนขับไม่ได้ยกเว้นทุกคนในครอบครัว 6 การเริ่มต้นตรวจสอบซีพียูในรายการรุ่นของซีพียูซึ่งครอบคลุมสถาปัตยกรรมไมโครทั้งหมดจาก Nehalem ถึง Kaby Lake Yorkfield มีอายุมากกว่านั้น (และแตกต่างอย่างมีนัยสำคัญ - Nehalem แตกต่างจากสถาปัตยกรรมที่มาก่อน) การทดสอบ Family 6 จะมีผลเฉพาะกับข้อความแสดงข้อผิดพลาดที่พิมพ์ออกมาหรือไม่ มันมีผลเฉพาะที่ข้อความแสดงข้อผิดพลาดจะปรากฏบน CPU ของ Intel เท่านั้นไม่ใช่ CPU ของ AMD (ตระกูลตระกูล 6 รวมถึง CPU ที่ไม่ใช่ NetBurst Intel ทั้งหมดตั้งแต่ Pentium Pro)intel_idle

เพื่อตอบคำถามการกำหนดค่าของคุณคุณสามารถปิดการใช้งานได้อย่างสมบูรณ์intel_idleแต่การทิ้งไว้ในนั้นก็ใช้ได้เช่นกัน (ตราบใดที่คุณไม่สนใจคำเตือน)


ข้อความ pr_debug () ควรปรากฏเฉพาะเมื่อคุณทำสิ่งที่เฉพาะเจาะจงเพื่อเปิดใช้งานข้อความดีบั๊กดังนั้นคุณไม่จำเป็นต้องเพิกเฉยต่อคำเตือน
sourcejedi

2
@sourcejedi ฉันพูดถึงว่าเพราะ OP กำลังเห็นมัน
Stephen Kitt

gotcha ฉันแสดงความคิดเห็นแบบครึ่งร้ายแรง: เนื่องจากเราถูกถามเกี่ยวกับการกำหนดค่าเคอร์เนลที่สมเหตุสมผลหากมีการใช้งานแบบวันต่อวันอาจไม่ใช้ตัวเลือกที่เปิดใช้งานข้อความดีบั๊กทั้งหมด ด้วยตัวเลือกที่ถูกต้องพวกเขาสามารถเปิดใช้งานแบบไดนามิกและเลือกเมื่อจำเป็น kernel.org/doc/html/v4.17/admin-guide/dynamic-debug-howto.html หากคุณเปิดใช้งานข้อความดีบั๊กทั้งหมดคุณอาจมีข้อความมากมายที่คุณไม่สนใจอยู่ดี :)
sourcejedi

@sourcejedi ฉันไม่เห็นความเกี่ยวข้องของความคิดเห็นของคุณเกี่ยวกับการปิดใช้งานข้อความเคอร์เนล ฉันไม่เห็นว่าสิ่งนี้เป็นสิ่งที่สร้างสรรค์สำหรับคำถามซึ่งเน้นการสนับสนุน Core 2 สำหรับintel_idleไดรเวอร์โดยเฉพาะ
vallismortis

@allismortis มันเป็นวงสัมผัสมาก หมายความว่ามีการกำหนดค่าที่ถูกต้องที่คุณสามารถใช้สำหรับ Core 2 และสูงกว่าซึ่งไม่ได้พิมพ์สิ่งนี้เป็นข้อความเตือนที่น่ารำคาญซึ่งจะต้องถูกละเว้นและจะใช้ intel_idle หากรองรับ ... แต่ฉันคิดว่าคุณจะใช้โหลดแบบไดนามิก อย่างไรก็ตามโมดูลดังนั้นอาจไม่คุ้มค่าที่จะกล่าวถึง
sourcejedi

6

มีวิธีที่เหมาะสมกว่าในการกำหนดค่าเคอร์เนลเพื่อรองรับ CPU idle ที่เหมาะสมที่สุดสำหรับโปรเซสเซอร์ตระกูลนี้หรือไม่ (นอกเหนือจากการปิดใช้งานการรองรับ intel_idle)

คุณเปิดใช้งาน ACPI และตรวจสอบว่ามีการใช้งาน acpi_idle ฉันสงสัยว่าคุณพลาดตัวเลือก config kernel ที่เป็นประโยชน์ คุณสามารถตรวจสอบpowertopคำแนะนำที่เป็นไปได้เสมอแต่คุณอาจรู้อยู่แล้วว่า


นี่ไม่ใช่คำตอบ แต่ฉันต้องการจัดรูปแบบ :-(

ดูซอร์สโค้ดเคอร์เนลไดรเวอร์ intel_idle ปัจจุบันมีการทดสอบเพื่อแยกตระกูล Intel 6 ออกจากไดรเวอร์โดยเฉพาะ

ไม่ไม่ :-)

id = x86_match_cpu(intel_idle_ids);
if (!id) {
    if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
        boot_cpu_data.x86 == 6)
        pr_debug(PREFIX "does not run on family %d model %d\n",
            boot_cpu_data.x86, boot_cpu_data.x86_model);
    return -ENODEV;
}

ifคำสั่งไม่ได้ยกเว้นครอบครัว 6. แทนifคำสั่งให้ผิดพลาดเมื่อมีการเปิดใช้การแก้จุดบกพร่องที่ว่านี้เฉพาะที่ทันสมัย CPU ของ Intel intel_idleไม่ได้รับการสนับสนุนโดย ในความเป็นจริงของ CPU i5-5300U ปัจจุบันของฉันเป็นครอบครัวที่ 6 intel_idleและจะใช้

สิ่งที่ยกเว้นซีพียูของคุณคือไม่มีการแข่งขันในintel_idle_idsตาราง

ฉันสังเกตเห็นความมุ่งมั่นนี้ซึ่งดำเนินการตาราง รหัสมันลบมีswitchคำสั่งแทน สิ่งนี้ทำให้ง่ายต่อการดูว่าโมเดลแรก intel_idle ถูกนำไปใช้ / ทดสอบสำเร็จแล้วหรืออะไรก็ตามที่เป็น 0x1A = 26 https://github.com/torvalds/linux/commit/b66b8b9a4a79087dde1b358a016e5c8739ccf186

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.