Mit Big-Little spendiert ARM Limited der Welt der Multicore-Architekturen eine neue, energiesparende Technologie. Die hat einen umfangreichen Umbau des Linux-Scheduling angestoßen – denn auch bei ARM-Prozessoren geht es nicht mehr allein um Performance.
Der Raspberry Pi hat das Marktsegment von Checkkarten-großen Minicomputern popularisiert und demokratisiert, das Hobbyisten und Bastlern neben preiswerter Rechenleistung auch die Kontrolle über die eigene Hardware zurückgibt. Neben dem unangefochtenen Segmentführer tummeln sich auf diesem Feld inzwischen zahlreiche andere Geräte wie der Banana Pi, der Cubietruck, das Hummingboard oder der Odroid XU.
Diese Raspberry-Pi-Alternativen bieten meist mehr Rechenleistung und eine flottere Netzanbindung, kosten dafür aber auch mehr (siehe Schwerpunkt dieser Ausgabe). Der Odroid XU stößt mit einem Preis von rund 180 Euro an die Decke des Leistungsspektrums. Was ihn besonders macht, verrät die Webseite des Herstellers (Abbildung 1): Den Minirechner treibt ein Octocore-Prozessor von Samsung an, der nach dem Big-Little-Prinzip arbeitet und Heterogeneous Multiprocessing (HMP) unterstützt.
Big-Little heißt eine von ARM Limited entwickelte Rechnerarchitektur ([1], [2]). ARMs Prozessordesign treibt die Mehrheit der aktuellen Smartphones und Tablets an.
Die Idee hinter Big-Little ist einfach: Man paare einige Hochleistungs-CPU-Kerne mit solchen, die wenig Strom brauchen, und wechsle abhängig von der Lastsituation zwischen beiden hin und her. Das optimiert den Stromverbrauch und verlängert die Laufzeit von Mobilgeräten.
ARM hat die Technik im Oktober 2011 vorgestellt, und gut drei Jahre später sind diverse Produkte auf dem Markt, zum Beispiel Samsungs Note-Produkte oder der erwähnte Odroid XU. Es gibt heute kaum eine Neuankündigung im Highend-Bereich, die auf Big-Little verzichtet.
Kompatible Paarung
Der einfachen Idee zum Trotz ist Big-Little technisch durchaus eine Herausforderung. Damit die Hardware zwischen zwei unterschiedlichen Prozessoren reibungslos hin und her schaltet, müssen beide identisch aufgebaut sein. Will ein Prozessor die Arbeit des anderen übernehmen, benötigt er alle prozessorinternen Zustände inklusive der Inhalte von Pipelines und Caches.
Daher lassen sich nicht beliebige Prozessoren paaren, sondern zurzeit vor allem die leistungsstarken Cortex-A15-Kerne mit den stromsparenden Cortex-A7 und ganz aktuell die 64-Bit-Kerne Cortex-A57 mit stromsparenden Cortex-A53. Völlig identisch sind Prozessoren auch in den Schnittstellen nach außen nicht. Das beginnt schon bei individuellen CPU-Kennungen und -Typen, ohne Softwaresupport geht also nichts.
In der ursprünglichen Variante hat ARM vorgeschlagen, mit Prozessorkern-Clustern zu arbeiten (Abbildung 2a). Diese kombinieren vier leistungsstarke Cortex-A15 mit vier stromsparenden Cortex-A7. Wird keine oder nur wenig Leistung angefordert, übernehmen die vier Cortex-A7-Kerne alle Aufgaben und die A15-Kerne machen Pause. Der Charme der Lösung besteht darin, dass sie dank Virtualisierungstechniken ohne Modifikationen an den Betriebssystemen auskommt.
Vier mal zwei
Flexibler ist die heute von vielen Geräten genutzte Variante, die statt der beiden Cluster mehrere CPU-Paare bildet (Abbildung 2b). Ein Octocore mit vier Cortex-A15- und vier Cortex-A7-Prozessoren erzeugt vier Paare und verkauft sie dem CPU-Scheduler als jeweils eine (virtuelle) CPU. Deren Taktfrequenz lässt sich dann in großem Umfang ändern.
Diese als In-Kernel-Switcher (IKS) bezeichnete Technik erfordert am Linux-CPU-Scheduling, das die Tasks auf die einzelnen Prozessoren verteilt, nur geringe Modifikationen. Dabei entscheidet die von der CPU angeforderte Leistung, ob das System vom kräftigen auf den stromsparenden Kern wechselt. Über die Taktfrequenz lassen sich ohnehin seit Jahren Performance und Stromverbrauch sowohl von x86- als auch von ARM-Prozessoren skalieren.
Im Linux-Kernel sind dafür die CPU-Frequency-Governors zuständig. Für Big-Little haben die Entwickler nicht den Scheduler selbst, sondern wesentlich die CPU Frequency Scaling Infrastructure (CPU-Freq) angepasst. Wechselt die Taktfrequenz, migriert diese – wenn nötig – Tasks zwischen der leistungsstarken und der stromsparenden CPU hin und her und aktiviert oder deaktiviert sie.
Eine Folge dieser Technik ist, dass die Android-App CPU-Identifier [3] auf einem mit Octocore (Exynos 5420) betriebenen Galaxy Note 10.1 (Version 2014, Modell P600) von den tatsächlich acht vorhandenen CPU-Kernen nur vier anzeigt, die im Bereich von 250 bis 1900 MHz arbeiten (Abbildung 3). Der In-Kernel-Switcher betreibt wissentlich nur die Hälfte der physisch vorhandenen CPU-Kerne.
Prozessorbaum
Diese Lösung empfanden sowohl Anwender als auch Entwickler als unbefriedigend. Technisch sprechen kaum Gründe dagegen, im Bedarfsfall alle Kerne zu nutzen – sieht man von einer höheren Hitze-Entwicklung ab. Allerdings erfordert dies einen Eingriff in das CPU-Scheduling des Linux-Kernels.
Das klassische Scheduling funktioniert unter Linux auf zwei Ebenen: Es gibt einen Singlecore-Scheduler und übergeordnet den Multicore-Scheduler. Während der Singlecore-Scheduler einem CPU-Kern Tasks zuordnet und damit die quasi-parallele Verarbeitung umsetzt, verteilt der Multicore-Scheduler Tasks auf die Kerne in einer Scheduling-Domain. Letzteres folgt einem baumartigen Modell [4]. Auf der untersten Ebene, den so genannten Blättern, gruppiert der Multicore-Scheduler CPU-Kerne in Scheduling-Domänen. Abhängig von der vorliegenden Hardware-Architektur ordnet Linux die Domänen einer Ebene wiederum einer übergeordneten Domäne zu.
Eine Intel-CPU mit zwei echten CPU-Kernen, die jeweils Hyperthreading (SMT) beherrschen und damit betriebssystemtechnisch wie vier CPU-Kerne erscheinen, modelliert es etwa über drei Domänen (Abbildung 4). Jeder echte CPU-Kern bildet mit seinen zwei Hyperthreading-Cores je eine Domäne (unterer Bereich in der Abbildung). Die dritte Domäne erzeugt Linux, indem es die beiden vereint (oberer Bereich in der Abbildung).
Performance plus Effizienz
Der Multicore-Scheduler verteilt Tasks auf die Domänen und kümmert sich um die Gleichverteilung der Last innerhalb einer Scheduling-Domäne. Die Load bestimmt, welche Tasks Linux innerhalb einer Domain und zwischen den Domänen verschiebt. Erst nachgelagert kümmern sich die CPU-Freq- und CPU-Idle-Governors um die Effizienz und das Deaktivieren von CPU-Kernen. Sie kooperieren dabei mit dem In-Kernel-Switcher (IKS).
Um alle Kerne einer Big-Little-Architektur zu nutzen, muss jemand den Scheduler modifizieren. Jemand ist in diesem Fall die ARM Limited nahestehende Firma Linaro, die das für Heterogeneous Multiprocessing (HMP) übernommen hat, das im Odroid XU sowie anderen Geräten zum Einsatz kommt (Abbildung 2c). Um die Verwirrung zu steigern, hat Linaro die Technologie inzwischen von HMP in Global Task Switching (GTS) umgetauft [5]. Das ermöglicht es, alle CPU-Kerne parallel zu nutzen, und erlaubt Systemarchitekturen mit einer unterschiedlichen Anzahl von Big- und Little-Kernen.
Global Task Switching
Am Global Task Switching ist bemerkenswert, dass es sich nicht mehr um klassisches symmetrisches Multiprocessing (SMP) handelt, sondern dass es in einer Scheduling-Domäne auch unterschiedliche CPU-Kerne unterstützt.
HMP-Systeme bilden typischerweise eine Domain mit leistungsstarken und eine mit stromsparenden CPU-Kernen. Innerhalb dieser beiden Domänen kommt das vorhandene Completly Fair Scheduling (CFS) zum Zuge [6]. Während der Multicore-Scheduler beim klassischen Linux-Scheduling die Last innerhalb der Domänen als Grundlage zur Task-Migration verwendet, zieht das GTS die Last aller Tasks zur Entscheidungsfindung heran (Abbildung 5).
Dazu ist es notwendig, das vorhandene Load Balancing auszuschalten und durch GTS zu ersetzen. Das verfolgt dann jede Task auf Basis ihrer Last, die sich aus der verbrauchten Time-Slice und dem Nice-Wert, also der Priorität, addiert. Rechenintensive Tasks, die eine hohe Last erzeugen, markiert GTS als solche und arbeitet sie auf einem Big-Kern in der leistungsstarken Domain ab. Wenig Last erzeugende Tasks bleiben auf einem Stromsparprozessor in der Stromspardomäne. Primäres Ziel ist nicht mehr, die Last ausgewogen zu verteilen, sondern den Stromverbrauch zu senken.
Zur Entscheidungsfindung benötigt GTS eine Liste der CPU-Kerne, die deren Leistungs- und Effizienzparameter umfasst. Neue Tasks startet es zunächst auf einer Big-CPU. Anhand von zwei Schwellenwerten migriert es die Tasks zwischen Scheduling-Domains oder nicht. Wird der untere Schwellenwert unterschritten, wandert die Task von einem Big- auf einen Little-Prozessor, beim oberen umgekehrt. Das soll ein ständiges Hin-und-her-Geschiebe von Tasks verhindern.
Tasks mit Echtzeitpriorität rührt GTS nicht an, sie bleiben auf der anfänglichen CPU. Laut Hersteller steigern all diese Bemühungen die Performance der Architektur um bis zu 20 Prozent und reduzieren den Stromverbrauch leicht.
Kernfrage
Wer jetzt im Quellcode des Mainline-Kernels nach Global Task Switching sucht, wird nicht fündig. Die Entwickler haben nicht einmal versucht den Code in die Mainline zu bekommen. Dazu setzt der Ansatz zu sehr auf den bisherigen Scheduling-Code auf, ist zu sehr auf die Big-Little-Architektur abgestimmt und zu unflexibel (siehe Kasten “Quellcode zum Global Task Switcher”).
Quellcode zum Global Task Switcher
Der Quellcode zum Global Task Switching findet sich nur auf den Webseiten von Linaro in der dort geführten Android-Version. Interessierte greifen über den Webbrowser [7] oder »git clone« [8] darauf zu.
Allerdings sind sich die Entwickler einig: Ein modernes Scheduling sollte nicht nur die Performance, sondern auch den Stromverbrauch berücksichtigen. An diesem Problem arbeiten sie zurzeit. Unter dem Arbeitstitel “Power aware Scheduler” (alternativ auch “Energy aware Scheduler”) hat Morten Rasmussen von ARM Limited auf der Kernel-Mailingliste einen Ansatz vorgestellt, den die Kernelhacker ausführlich diskutieren, kommentieren und positiv begleiten ([9], [10]).
Allgemein statt speziell
Die Grundidee des Power Aware Scheduler besteht darin, den Load Balancer, der die Aufgaben auf die CPU-Kerne verteilt, zu modifizieren. Der Load Balancer soll die aktuelle Auslastung der Cores stärker berücksichtigen und mehr Informationen über den Hardware-Aufbau und die Eckdaten der CPU-Kerne nutzen, etwa die Rechenleistung und den Stromverbrauch. Zudem soll er CPUs hoch- und runtertakten (CPU-Freq) und CPU-Kerne abschalten (CPU-Idle).
Damit der neue Load Balancer diese Forderungen erfüllt, führt Morten eine Abstraktionsschicht für den Power-Scheduler ein (Abbildung 6). Diese liefert plattformunabhängig Informationen über die aktuellen Leistungsdaten der einzelnen CPU-Kerne. Außerdem reicht sie Wünsche – zum Beispiel »go_faster()« oder »go_slower()« – an so genannte Power-Treiber weiter. Diese beeinflussen die Zustände der CPU-Kerne und führen ein Leistungs- und Energie-Monitoring durch. Dazu melden sie sich beim Power-Scheduler an.
Entscheidend ist natürlich der Algorithmus, der die Tasks verteilt und die Leistung anpasst, indem er Prozessoren hoch- und runtertaktet und ihre Performance-Zustände ändert. Auch die CPU-Kerne soll er zu- und abschalten können (Sleep-Zustände). Auch muss er Fälle abdecken, in denen drei stromsparende Prozessoren bei weniger Energie-Einsatz mehr Rechenleistung bieten als ein leistungsstarker wie etwa beim Gespann Cortex-A15 und Cortex-A7.
Die Jobs auf die drei stromsparenden Prozessoren zu verschieben und den leistungsstarken zu deaktivieren ergibt aber nur Sinn, wenn die Tasks multithreaded programmiert sind. Das ist nur ein Beispiel für die Komplexität des Themas, ein weiteres besteht darin, die Zeit zu verrechnen, die das Schlafenlegen und Aufwecken eines CPU-Kerns benötigt.
Langfristig terminiert
Bis zu einer allgemeinen Lösung, die alle wesentlichen Einsatzfälle abdeckt und ausreichend gut handhabt, dürften noch einige CPU-Takte verstreichen. Die Entwicklungsrichtung allerdings steht fest: Scheduling wird nicht länger als Frage der reinen Performance betrachtet, sondern berücksichtigt auch den Energieverbrauch beziehungsweise die generelle Effizienz. Das lässt auf spannende Entwicklungen für künftige Generationen von ARM-Prozessoren hoffen.
Infos
- Jan Richling, Anselm Busse, “ARM gestern, heute, morgen”: Linux-Magazin 06/13, S. 22, https://www.linux-magazin.de/Ausgaben/2013/06/ARM-Architektur
- Brian Jeff: “Ten Things to Know About Big-Little”: http://community.arm.com/groups/processors/blog/2013/06/18/ten-things-to-know-about-biglittle
- CPU-Identifier-App: https://play.google.com/store/apps/details?id=com.Bfield.CpuIdentifier&hl=de
- Quade, Kunst, “Kern-Technik”: Linux-Magazin 05/07, S. 52, https://www.linux-magazin.de/Ausgaben/2007/05/Kern-Technik
- Mathieu Poirier, “GTS – A solution to ARM’s Big-Little technology”: http://de.slideshare.net/linaroorg/lca14-104-gtsasolutiontoarmsbiglittletechnology?related=1 und http://www.youtube.com/watch?v=PmBT52hBAZg
- Quade, Kunst, “Kern-Technik”: Linux-Magazin 04/13, S. 96, https://www.linux-magazin.de/Ausgaben/2013/04/Kern-Technik
- GST-Code auf Linaros Webseite: http://releases.linaro.org/latest/android/vexpress-lsk
- Linaro-Code im Git: http://git.linaro.org/kernel/linux-linaro-stable.git
- Morten Rasmussen auf der LKML: https://lkml.org/lkml/2014/7/3/884
- Energy aware Scheduling: https://rt.wiki.kernel.org/index.php/Energy_Aware_Scheduling












