- cpuidle oddziela zasady i mechanizmy poprzez stosowanie zarządców i sterowników do zarządzania stanami uśpienia procesora.
- Wybór stanu odbywa się na podstawie miejsca zamieszkania użytkownika, opóźnienia wyjściowego, historii bezczynności i nadchodzących timerów.
- Warunkiem jakości usług PM i harmonogramu tyknięć jest to, że głębokie stany mogą być używane bez naruszania wymagań dotyczących opóźnienia.
- W ARM i innych nowoczesnych układach SoC procesor jest zintegrowany z oprogramowaniem sprzętowym za pośrednictwem PSCI, co ma kluczowe znaczenie dla rzeczywistego zużycia energii i czasu pracy baterii.
Jeśli używasz Linuksa na laptopie, komputerze stacjonarnym lub płycie głównej ARM i martwisz się, bateria, ciepło, czyli dlaczego procesor nie przechodzi w stan uśpienia „tak jak powinien”, zrozumieć jak działa podsystem cpuidle To klucz. Za czymś pozornie tak prostym jak „procesor jest bezczynny” kryje się dość skomplikowany mechanizm, który decyduje jaki stan odpoczynku zastosować, jak długo spać i ile czasu zajmuje obudzenie się.
Ponadto, jeśli pochodzisz z projektów takich jak Asahi Linux na Macu z M1/M2To normalne, że się mylisz: mówimy o kierowcach cpuidle...z niedojrzałych lub całkowicie nieobecnych stanów spoczynkowych, i to właśnie uniemożliwia codzienne korzystanie z systemu. W tym artykule spokojnie omówimy... Czym właściwie jest cpuidle, jak działa wewnętrznie, jaką rolę odgrywają regulatory i sterowniki, jak się go konfiguruje, jakie opcje jądra na niego wpływają i jak integruje się z nowoczesnymi platformami ARM? takich jak te wykorzystujące PSCI lub TF-A.
Czym jest podsystem cpuidle i dlaczego istnieje?
Dekady temu stan „bezczynności” jądra był pustą pętlą : gdy nie było nic do wykonania, uruchamiana była pętla bezczynności, w zasadzie nieskończona pętla oczekująca na kolejne przerwanie. Samo niewykonywanie złożonego kodu pozwalało zaoszczędzić trochę energii: pamięć podręczna, jednostka FPU itp. nie były tak intensywnie wykorzystywane.
Wraz z rozwojem sprzętu, procesory zaczęły oferować wiele stanów bezczynności (stany C, stany bezczynności) , z których każdy charakteryzował się różnymi poziomami oszczędności energii i karami: wejście w stan głęboki może zaoszczędzić dużo energii, ale wejście i wyjście z niego zajmuje więcej czasu i energii . Jeśli wejdziesz w stan zbyt głęboki i zostaniesz zbyt szybko wybudzony, przegrałeś.
W tym miejscu do gry wkracza cpuidle , podsystem jądra dedykowany do zarządzania czasem bezczynności procesora . Jego zadaniem jest decydowanie, kiedy procesorowi kończą się zadania (pozostają tylko zadania bezczynne), o najlepszym stanie uśpienia, jaki może zastosować, aby oszczędzać energię bez zakłócania opóźnienia reakcji.
Koncepcyjnie cpuidle oddziela dwie części: z jednej strony mechanizm (sterowniki) , który potrafi komunikować się ze sprzętem i wyliczać stany bezczynności, a z drugiej strony politykę (regulatory) , która decyduje, który konkretny stan zostanie użyty w danym momencie, na podstawie historii bezczynności, nadchodzących timerów i ograniczeń opóźnienia.
Wszystko to dzieje się w pętli bezczynności : gdy harmonogram widzi, że procesor nie ma już żadnych zadań do wykonania, uruchamia specjalne zadanie „bezczynności”, którego kod najpierw wywołuje regulator w celu wybrania stanu, a następnie sterownik, aby go wprowadzić.

Procesory logiczne, zadania bezczynne i co oznacza bycie bezczynnym
Podsystem cpuidle zawsze działa w oparciu o logiczne procesory , czyli jednostki, które widzi harmonogram: mogą to być rdzenie fizyczne, wątki sprzętowe (hiperwątki) lub ich kombinacje, w zależności od architektury i implementacji.
Z perspektywy jądra, logiczny procesor jest „bezczynny”, gdy nie ma powiązanych z nim żadnych zadań wykonywalnych poza samym zadaniem bezczynnym . Harmonogram zarządza procesami i wątkami jako „zadaniami”, które mogą znajdować się w różnych stanach; gdy zadanie staje się wykonalne, jest ono przypisywane do procesora. Jeśli procesorowi pozostaje tylko bezczynne zadanie, jądro uznaje je za nieaktywne.
Zadanie bezczynne wykonuje połączenie pętla bezczynnościTa pętla, w każdej iteracji, wywołuje regulator cpuidle, aby zdecydować o stanie uśpienia, a następnie wywołuje sterownik cpuidle, aby zażądać od sprzętu przejścia w ten stan. Jeśli nie ma dostępnych stanów uśpienia, brakuje czasu do następnego zdarzenia lub ograniczenia dotyczące opóźnienia są zbyt rygorystyczne, procesor albo wykonuje stosunkowo bezużyteczną pętlę, albo używa najprostszej instrukcji wait (takiej jak `wait`). hlt lub podobne).
W procesorach wielordzeniowych lub SMT decyzje dotyczące bezczynności wpływają na hierarchie jednostek : żądanie uśpienia na poziomie wątku może spowodować przejście rdzenia w stan głębszy, jeśli wszystkie wątki są bezczynne, a klaster rdzeni może przejść w stan uśpienia, jeśli wszystkie jego elementy na to pozwolą. Program cpuidle musi modelować to za pomocą stanów reprezentujących kombinacje poziomów hierarchicznych , z opóźnieniami i rezydencjami odzwierciedlającymi najgłębszy możliwy stan.
Gdy żądany jest stan reprezentowany przez obiekt typu struct cpuidle_stateSterownik może zezwolić sprzętowi na zagłębienie się na taką głębokość, na jaką pozwala projekt. Dlatego Opóźnienie wyjściowe i miejsce docelowe muszą być zgodne z rzeczywistą kombinacją najgorszego przypadku stanu w ramach hierarchii (rdzeń, klaster, pakiet itd.).
Gubernatorzy CPUIDLE: jak decydują, który stan wykorzystać
Regulatory bezczynności procesora (CPU Idle Governors) to moduły polityki , które uruchamiają się za każdym razem, gdy procesor wchodzi w pętlę bezczynności. Ich celem jest wykorzystanie dostępnych informacji do wybrania stanu bezczynności, który oszczędza najwięcej energii bez naruszania ograniczeń dotyczących opóźnień.
Każdy gubernator jest definiowany jako struktura struct cpuidle_governorz wywołaniami zwrotnymi enable, disable, select y reflect, pole priorytetowe (rating) i imię. Po zarejestrowaniu się cpuidle_register_governor(), może zostać wybrany automatycznie przez jądro (na podstawie oceny, domyślnej konfiguracji lub parametru) cpuidle.governor=) lub ręcznie z przestrzeni użytkownika poprzez sysfs.
Gdy regulator jest aktywowany dla procesora za pomocą wywołania zwrotnego enable(), otrzymuje struct cpuidle_device który reprezentuje ten procesor i struct cpuidle_driver z listą dostępnych stanów (struct cpuidle_state). tak enable() Jeśli się nie powiedzie, jądro użyje domyślnego kodu bezczynności. specyficzne dla architektury zamiast cpuidle dla tego procesora.
Sercem gubernatora jest odwoływanie select()który odbiera urządzenie cpuidle, sterownik i wskaźnik do wartości logicznej stop_tickTa funkcja zwrotna zwraca indeks wybranego stanu w tablicy stanów lub ujemny kod błędu. Dodatkowo może zdecydować, czy zatrzymać harmonogram taktowania na danym procesorze (czyszcząc wartość logiczną lub nie).
Gdy procesor się obudzi, gubernator otrzyma wezwanie do reflect() z informacją o tym, który stan został wybrany i jak długo faktycznie trwał przestój. Pozwala to udoskonalać swoje przewidywania na podstawie danych historycznychNależy również przestrzegać ograniczeń dotyczących opóźnień QoS PM: cpuidle_governor_latency_req() uzyskuje efektywny limit opóźnienia i nigdy nie powinien wybierać stanu, którego exit_latency przekroczyć tę wartość.
Główni zarządcy: ladder, haltpoll, menu i teo
W Linuksie istnieje kilka zarządców cpuidle, z których każdy ma własną strategię i grupę docelową. Cztery główne to ladder, haltpoll, menu i teo , a wybór domyślnego zarządcy w dużej mierze zależy od tego, czy jądro jest bezkluczowe (zdolne do zatrzymania harmonogramu ticków), czy nie.
Drabinka została zaprojektowana dla systemów z aktywnym tykaniem okresowym. Wykorzystuje proste podejście oparte niemal wyłącznie na historii czasu bezczynności : porusza się w górę i w dół „drabiny” stanów, awansując do stanów głębszych, gdy wykryje wystarczająco długi czas bezczynności, i wycofując się, gdy wybudzenia następują zbyt wcześnie.
haltpoll to wyspecjalizowany kontroler maszyn wirtualnych. Zamiast wprowadzać sprzęt w stan głębokiego bezczynności, opiera się on w dużej mierze na sondowaniu (pętlach oczekiwania), aby zmniejszyć pozorne opóźnienia w środowiskach, w których fizyczne stany bezczynności mogą nie mieć większego znaczenia lub nie są dobrze modelowane przez hiperwizor.
menu y theo Są to regulatory stosowane w systemach beztykających (CONFIG_NO_HZ_IDLE o CONFIG_NO_HZ_FULLOba łączą w sobie Historia okresów bezczynności z informacją o następnym timerzei starają się oszczędzać energię, nie spędzając na obliczaniu decyzji więcej czasu, niż można zaoszczędzić, podejmując decyzję.
Menu regulatora próbuje jednoznacznie przewidzieć, jak długo procesor będzie bezczynny . Wykorzystuje czas do następnego timera jako górny limit i stosuje współczynnik korekcji oparty na historii ostatnich bezczynności, aby przybliżyć „typowy” czas trwania. Na podstawie tej przewidywanej wartości, konsultuje tabelę stanów, aby wybrać najgłębszy stan, którego docelowy czas trwania jest zgodny.
Regulator TEO (Timer-Event Oriented) podchodzi do problemu inaczej: zamiast próbować przewidywać dokładny czas przestoju, kwantyfikuje dane historyczne w „przedziałach” lub przedziałach czasu powiązanych z każdym stanem . Każdy przedział odpowiada zakresowi czasu, w którym dany stan jest zazwyczaj optymalny. TEO przechowuje metryki dla trafień (wybudzeń, których rzeczywisty czas trwania ściśle odpowiada docelowemu czasowi przebywania) i przechwyceń (wybudzeń spowodowanych zdarzeniami niezwiązanymi z czasem, które zakłócają prognozę) i, na podstawie tych informacji, bezpośrednio wnioskuje, który konkretny stan jest najprawdopodobniej prawidłowy.
Tylko wtedy, gdy jest to korzystne, TEO sprawdza czas do następnego timera, aby uniknąć wejścia w stan, którego docelowa długość pobytu jest większa niż faktycznie dostępne okno . Co więcej, jego konstrukcja ma na celu ograniczenie kosztów decyzyjnych: w scenariuszach z bardzo krótkimi czasami bezczynności lepiej jest szybko wybrać stan płytki niż marnować więcej energii na myślenie, niż się zaoszczędzi.
Sterowniki procesora: most między jądrem a sprzętem
Podczas gdy gubernatorzy są zajęci polityką, sterowniki procesora implementują rzeczywisty mechanizm wejścia/wyjściaKażdy sterownik reprezentuje listę stanów obsługiwanych przez procesor (lub zestaw procesorów) za pośrednictwem struct cpuidle_driver który zawiera tablicę struct cpuidle_state.
Każdy struct cpuidle_state definiuje między innymi miejsce zamieszkania (target_residency w mikrosekundach), maksymalne opóźnienie wyjściowe (exit_latency), flagi takie jak CPUIDLE_FLAG_POLLING i co bardzo ważne, oddzwonienie enter() który wykonuje delikatną część: wykonuje instrukcje lub wywołania niezbędne do tego, aby sprzęt wszedł w dany stan.
Wpisy w tablicy stanów muszą być sortowane rosnąco według wartości target_residency , tak aby indeks 0 zazwyczaj odpowiadał najpłytszemu (i najtańszemu w użyciu) stanowi, a kolejne indeksy były powiązane ze stanami coraz głębszymi. Zarządcy przyjmują to sortowanie w swoich obliczeniach.
Odwołanie zwrotne enter() otrzymuje urządzenie cpuidle, sterownik i indeks stanu do użyciaW przypadku typu zawieszenia zawieszenie do biegu jałowego, jest używany zamiast enter_s2idle()który musi spełniać bardziej rygorystyczne ograniczenia: nie może ponownie aktywować przerwań ani manipulować urządzeniami czasowymi podczas wykonywania, czego enter() Tak, jest to możliwe w zależności od platformy.
Oprócz opisywania stanów sterownik musi rejestrować, które procesory znajdują się pod jego kontrolą: każdy procesor ma swój własny struct cpuidle_device, który jest zwykle rejestrowany w cpuidle_register_device()Jeżeli nie ma stanów „sprzężonych” (wymagających koordynacji między wieloma procesorami), rejestr jest wykonywany za pomocą cpuidle_register_driver()Jeśli są, to są używane cpuidle_register()która odpowiada również za rejestrację urządzeń.
Nowoczesne platformy starają się ograniczyć liczbę konkretnych sterowników: na przykład ARM zazwyczaj używa sterownika ogólnego, który delegować do standardowych interfejsów, takich jak PSCI (Power State Coordination Interface)W RISC-V coś podobnego poprzez SBI (Supervisor Binary Interface). Mimo to, takie sterowniki nadal istnieją w architekturze x86. intel_idle (z tabelą stanów „wgraną” do sterownika) i acpi_idle (który pobiera stany z tabel ACPI).
Stany bezczynności: parametry, sysfs i metryki
Każdy stan spoczynku, który cpuidle udostępnia regulatorom, charakteryzuje się kilkoma głównymi parametrami. Dwa najważniejsze to miejsce zamieszkania (target_residency) i opóźnienie wyjściowe (exit_latency), oba w mikrosekundach.
La target_residency W praktyce oznacza to energetyczną głębię stanu.Jest to minimalny czas, przez jaki sprzęt musi pozostać w tym stanie (wliczając koszt wejścia), aby był opłacalny w porównaniu ze stanami płytszymi. Jeśli system wybudzi się przed osiągnięciem tego czasu, prawdopodobnie zużył więcej energii na wejście w ten stan, niż zaoszczędził.
La exit_latency Określa najgorszy możliwy czas, jaki musi upłynąć od momentu, gdy procesor zażąda wyjścia z danego stanu, do momentu faktycznego wykonania kolejnej użytecznej instrukcji.Dotyczy to również przypadku, gdy zdarzenie wybudzenia następuje, gdy sprzęt wciąż wchodzi w ten stan, ponieważ z reguły wewnętrzne przejście musi zostać ukończone, zanim sprzęt będzie mógł wyjść z niego w uporządkowany sposób.
Ponadto istnieją flagi opisujące dodatkowe właściwości stanu, na przykład: CPUIDLE_FLAG_POLLING oznacza, że ten „stan” nie jest w rzeczywistości stanem spoczynku sprzętowegoale pętla sondowania, która jest używana jako specjalny mechanizm, aby uniknąć modyfikowania rzeczywistych stanów, gdy jest to wygodne (na przykład w niektórych środowiskach wirtualizowanych lub debugowania).
Jądro udostępnia bardzo szczegółowe informacje o stanach bezczynności procesora za pośrednictwem sysfs, w /sys/devices/system/cpu/cpu<N>/cpuidle/Znajdują się tam katalogi. state0, state1itd., po jednym dla każdego wejścia tablicy sterowników, a w każdym z nich możemy znaleźć atrybuty takie jak name, desc, latency, residency, usage, time, power, above, below y rejected.
Te atrybuty pozwalają nam zobaczyć ile razy każdy stan został poproszony (usage), ile czasu łącznie poświęcono na to zgodnie z jądrem (time)i w jakim stopniu wybór był dobry lub zły (above y below Zliczają przypadki, w których rzeczywisty czas bezczynności był wyraźnie za krótki lub za długi w stosunku do miejsca zamieszkania). rejected Zlicza przypadki odrzucenia żądania, zazwyczaj z powodu przerwania, które nastąpiło tuż w momencie przejścia.
Istnieje jeden szczególnie przydatny atrybut, disableUmożliwia to aktywację lub dezaktywację tego konkretnego stanu dla procesora z przestrzeni użytkownika (poprzez wpisanie 1 lub 0). Jeśli ta opcja jest wyłączona dla procesora, regulator nie będzie jej uwzględniał przy wyborze; jeśli chcesz całkowicie usunąć stan systemu, musisz… wyłącz to na wszystkich procesorach. Atrybut default_status wskazuje, czy stan jest domyślnie włączony czy nie.
Harmonogram kleszczy i systemy bezkleszczowe
Słynny tykanie harmonogramu Jest to zegar okresowy (100, 250 lub 1000 Hz, w zależności od CONFIG_HZ) którego jądro używa między innymi do przydzielania czasu procesora zadaniom, aktualizowania liczników i wyzwalania wygaśnięcia timerów.
Z punktu widzenia cpuidle okresowe taktowanie jest uciążliwe: dopóki procesor jest aktywny, a jego działanie nie jest możliwe, procesor nie może spać dłużej niż okres taktu , a ponadto każde wybudzenie na takt wiąże się z wejściem w stan uśpienia i wyjściem z niego, co powoduje marnotrawienie energii, jeśli wybrany zostanie zbyt głęboki stan uśpienia.
Zgodnie z definicją, na procesorze, który uruchamia tylko pętlę bezczynności Nie jest konieczne trzymanie kleszcza W przypadku współdzielenia procesora: nie ma już zadań do wykonania. Dlatego system Linux można skonfigurować jako bez łaskotania w stanie bezczynności (CONFIG_NO_HZ_IDLE) lub w trybie „pełnym”, gdy na procesorze znajduje się tylko jedno odizolowane zadanie (CONFIG_NO_HZ_FULL), dezaktywując kleszcza w tych warunkach.
Decyzję o zatrzymaniu kleszcza podejmuje regulator na podstawie parametru stop_tick z Twojego połączenia zwrotnego select()Jeżeli spodziewasz się przerwy (związanej z timerem lub inną) w krótkim okresie (w ciągu okresu, który byłby okresem tykania), Nie ma sensu dezaktywować kleszcza.Wymagałoby to czasu na przeprogramowanie, a okres przestoju mógłby być spędzony w zbyt płytkim stanie, jeśli okazałoby się, że nikt nie budzi procesora.
Odwrotnie, jeśli gubernator uważa, że procesor będzie bezczynny dłużej niż tyk, a wybrany stan jest głęboki, Najlepiej zatrzymać tykanie, żeby nie zrujnować oszczędnościNiektóre konfiguracje jądra (parametr nohz=off lub wyłącz CONFIG_NO_HZ_IDLE) wymuszają, aby tykanie nigdy się nie kończyło, w takim przypadku system nie jest beztykający, a domyślnym zarządcą jest zwykle drabinka, a nie menu lub teo.
PM QoS: Jak kontrolować opóźnienia spoczynkowe
Struktura jakości usług zarządzania energią (PM QoS) umożliwia sterownikom i procesom przestrzeni użytkownika wyrażanie ograniczeń dotyczących zachowania energetycznego systemu, w szczególności w zakresie opóźnień wejścia/wyjścia w stanach uśpienia.
W przypadku cpuidle występują dwa główne typy ograniczeń: globalny limit opóźnienia procesora i ograniczenia Opóźnienie wznowienia procesora (pm_qos_resume_latency_us)Wewnętrznie żądania są przechowywane na listach priorytetów, a wartością efektywną jest w tym przypadku najmniejsza wartość ze wszystkich żądań.
Z przestrzeni użytkownika można modyfikować limit globalny, otwierając /dev/cpu_dma_latency i zapisując w tym deskryptorze 32-bitową liczbę całkowitą o maksymalnym tolerowanym opóźnieniu w mikrosekundach. Każdy otwarty deskryptor reprezentuje niezależne żądaniePo zamknięciu żądanie znika, a system ponownie oblicza wartość efektywną, biorąc pod uwagę pozostałe.
W przypadku ograniczeń procesora istnieje plik power/pm_qos_resume_latency_us en /sys/devices/system/cpu/cpu<N>/Zapisanie tam wartości zmienia żądanie powiązane z danym procesorem (współdzielone przez całą przestrzeń użytkownika, dlatego zaleca się arbitraż dostępu do niego). Sterowniki jądra mogą również rejestrować własne żądania za pośrednictwem wewnętrznych interfejsów API PM QoS.
Gubernatorzy cpuidle muszą w każdym wyborze stanu: należy zachować minimum pomiędzy efektywnym opóźnieniem globalnym a opóźnieniem procesora, którego to dotyczyNie mogą wybierać państw, których exit_latency przekroczyć ten limit. Jest to niezwykle ważne w przypadku oprogramowania z miękkie wymagania w czasie rzeczywistym, takich jak dźwięk lub obraz, gdzie zbyt wolne wznowienie z głębokiego stanu może spowodować niedobory lub zakłócenia.
Istnieje również inny QoS, cpu_wakeup_latencyco wpływa na wybór stanów bezczynności w trybie zawieszenie do biegu jałowego (s2idle) systemu. Jego obsługa z przestrzeni użytkownika jest podobna do cpu_dma_latency i jest również wyrażany w mikrosekundach.
sterowanie procesorem za pomocą parametrów jądra
Linux pozwala dostosować zachowanie sterowników cpuidle i idle z poziomu wiersza poleceń jądra. Najbardziej drastycznym parametrem jest cpuidle.off=1Spowoduje to całkowite wyłączenie podsystemu: pętla bezczynności nadal istnieje, lecz regulatory i sterowniki cpuidle nie są już wywoływane, a zamiast tego używany jest „domyślny” mechanizm architektury, który jest zazwyczaj znacznie prostszy i mniej wydajny.
Parametr cpuidle.governor=<nombre> Pozwala na wymuszenie na gubernatorze użycia np. cpuidle.governor=menu o cpuidle.governor=teo, zamiast tego, który byłby wybierany automatycznie. Jest to przydatne do eksperymentowania z poborem mocy i opóźnieniami na tym samym sprzęcie bez konieczności rekompilacji jądra.
W architekturach x86 istnieją również specyficzne parametry dotyczące sposobu przechodzenia w tryb bezczynności. Na przykład: idle=halt y idle=poll Wyłączają sterowniki. intel_idle y acpi_idlezmuszając system do użycia instrukcji hlt lub czystej pętli sondowania dla reszty. Upraszcza to zachowanie, ale kosztem wydajności: idle=pollW szczególności może zapobiec stosowaniu stanów P, które wymagają bezczynności procesora, co pogarsza zużycie energii i wydajność pojedynczego wątku.
Parametr idle=nomwait zabrania użycia instrukcji MWAIT do wejścia w stan uśpienia, wymuszając acpi_idle używać hlt i dezaktywacja intel_idle W procesorach Intel stanami zarządza wyłącznie ACPI. Co więcej, sterowniki intel_idle y processor (ten ostatni obejmuje) acpi_idle) akceptują opcje takie jak intel_idle.max_cstate=<n> y processor.max_cstate=<n> aby zawęzić listę dostępnych stanów w sterowniku i odrzucić wszystkie, które znajdują się głębiej niż określony indeks.
W przypadku intel_idle.max_cstate=0Jest to równoznaczne z wyłączeniem konkretnego sterownika Intel i umożliwieniem przejęcia kontroli przez sterownik ACPI, podczas gdy processor.max_cstate=0 jest interpretowane jako processor.max_cstate=1Są to przydatne opcje dla w celu diagnozowania problemów ze stabilnością, nieprawidłowych opóźnień lub nietypowego zużycia energii, kosztem ograniczenia zdolności systemu do oszczędzania energii w stanie bezczynności.
Integracja z platformami ARM, PSCI i standby
Na nowoczesnych platformach ARM (takich jak wiele układów SoC firm TI, NXP, Rockchip, Apple za pośrednictwem Asahi itp.), procesor cpuidle jest zazwyczaj zintegrowany z oprogramowaniem układowym niskiego poziomu za pośrednictwem PSCI i jest powszechnie stosowany w urządzeniach IoT z inteligentnym zarządzaniem usługami IoT . Generyczny sterownik ARM dla procesora cpuidle komunikuje się z PSCI za pomocą Secure Monitor Calls (SMC) i deleguje rzeczywiste przejścia stanu do oprogramowania układowego Arm Trusted Firmware (TF-A) lub równoważnego.
Typowym przykładem jest układ SoC, taki jak AM62x, w którym stan czuwania jest realizowany jako stan CPUIdle (bezczynności procesora) w oparciu o instrukcję WFI (Wait For Interrupt) . Z perspektywy użytkownika, system przechodzi w stan czuwania i wychodzi z niego w sposób ciągły, wiele razy na sekundę, bez konieczności jakiejkolwiek interakcji: jest to domyślny, „lekki” stan uśpienia, z czasami wejścia i wyjścia rzędu mikrosekund.
Ścieżka wykonania, gdy system przechodzi w tryb bezczynności na tych platformach, wygląda w przybliżeniu następująco: Pętla bezczynności wykrywa brak zadań i regulator wybiera odpowiedni stan (na przykład taki, który nazywa się stby)Ogólny sterownik ARM wywołuje PSCI przez warstwę drivers/firmware/psci.c, a po stronie TF-A wywoływany jest handler cpu_standby() zdefiniowane w strukturze plat_psci_opsTam to się naprawdę dzieje. WFI.
Po wystąpieniu przerwania procesor automatycznie wychodzi z trybu WFI, TF-A zwraca kontrolę jądru, a procesor kontynuuje wykonywanie od miejsca, w którym przerwał. Wszystko to jest organizowane transparentnie, pod warunkiem… drzewo urządzeń dokładnie opisuje stany bezczynności (węzeł idle-states, odwołania z każdego procesora i właściwości takie jak entry-latency-us, exit-latency-us y min-residency-us).
Tego lekkiego trybu uśpienia procesora nie należy mylić z pełnymi trybami głębokiego uśpienia na poziomie systemu , w których wyłączane są całe bloki zasilania, rekonfigurowane są urządzenia peryferyjne, a czasy wejścia/wyjścia mieszczą się w milisekundach lub sekundach. Stany bezczynności procesora (CPUidle) są bardziej ukierunkowane na mikrozarządzanie krótkotrwałym uśpieniem , podczas gdy tryby głębokiego uśpienia wymagają dodatkowej koordynacji ze strony menedżera zadań (PM) w czasie wykonywania, wstrzymania/wznowienia działania sterownika oraz często specyficznego wsparcia w bootloaderze lub oprogramowaniu układowym.
Gdy jądro ma włączoną funkcję cpuidle i działający sterownik (na przykład ogólny sterownik ARM + PSCI, poprawnie opisany w DT), Użytkownik nie musi niczego „aktywować”.Gubernatorzy zajmują się tym automatycznie. Można jednak sprawdzić statystyki w /sys, zmienić obecnego gubernatora w /sys/devices/system/cpu/cpuidle/current_governor lub dostosować właściwości stanów udostępnianych przez sterownik.
Na stosunkowo nowych platformach lub w procesach portowania, takich jak Asahi Linux, wiele problemów z żywotnością baterii, przegrzewaniem się lub brakiem funkcjonalnego trybu uśpienia jest związanych z faktem, że pełna integracja cpuidle ze sprzętem nie jest jeszcze ukończona (lub dojrzała) : w dokumentacji programistycznej brakuje dobrze opisanych stanów, nie ma oprogramowania układowego implementującego sensowne stany lub sterownik jest wciąż w fazie rozwoju. Dopóki sytuacja się nie ustabilizuje, często używa się jedynie bardzo powierzchownego stanu Wi-Fi lub, co gorsza, całkowicie wyłącza się cpuidle, co skutkuje raczej prymitywnym trybem uśpienia.
Ostatecznie zrozumienie, w jaki sposób cpuidle modeluje logiczne procesory, w jaki sposób regulatory podejmują decyzje dotyczące docelowych rezydencji, opóźnień i jakości usług PM , w jaki sposób sterowniki łączą się z ACPI, PSCI lub zastrzeżonym oprogramowaniem sprzętowym i w jaki sposób harmonogram tykania warunkuje okresy bezczynności, pozwala dostrzec w nowym świetle, dlaczego laptop działa dłużej (lub krócej) na baterii, dlaczego jądro „bez tykania” zwykle zużywa mniej energii i dlaczego w przypadku niektórych portów do egzotycznego sprzętu, uśpienie i bezczynność dosłownie różnią się między systemem testowym a użytecznym codziennym sterownikiem.
Pisarz z pasją zajmujący się światem bajtów i technologii w ogóle. Uwielbiam dzielić się swoją wiedzą poprzez pisanie i właśnie to będę robić na tym blogu, pokazywać Ci wszystkie najciekawsze rzeczy o gadżetach, oprogramowaniu, sprzęcie, trendach technologicznych i nie tylko. Moim celem jest pomóc Ci poruszać się po cyfrowym świecie w prosty i zabawny sposób.