News Ampere Computing: Zweimal 192 Kerne sind schon zu viel für Linux

bluedxca93 schrieb:
Super und wieviele mhz liegen dann an den jeweiligen Kernen an und wie gros ist der Befehlssatz vom den Kernen? Was kann man damit tun?
Vieles :)
 
=rand(42) schrieb:
Ist trotzdem ärgerlich, wenn man die neue Hardware hat, die eigene Distro den default-Wert lässt und man dshalb den Kernel neu compilieren müsste...
Naja, es ist aber schon fraglich, ob jemand, der sich einen Server mit fast 400 Arm-Kernen kauft, etwa ein Ubuntu mit Standard-Kernel darauf laufen lässt
 
rg88 schrieb:
Und mal abgesehen davon muss man auch noch sagen:
Die haben seit einem halben Jahr die Technik am Markt und kommen JETZT mit einem Linux-Patch daher?
Warum das nicht während den Jahren Entwicklungszeit davor schon?
Ich wiederhole mich: Der Kernel kann derzeit mit 2^13 Kernen umgehen. Was Ampere ändern wollte ist, ein default Buildparameter ändern und die Möglichkeit cpumask_offstack zu aktivieren, wenn die Anzahl der CPU Kerne größer ist als der Buildparameter. Diskussionen dazu gab es vor dem eingereichten Patch.
Buildparameter ändern und es war bereits seit langem möglich den Kernel für dicke Systeme zu bauen.


Weyoun schrieb:
Welche ungewollten Nebenwirkungen holt man sich mit der Option CPUMASK_OFFSTACK ins Haus?
Man kann mehr Kerne betreiben, aber zu welchem Preis gegenüber einer "offiziellen" Unterstützung von mehr Kernen?
Muss halt CPU Zyklen auf dynamische Speicherverwaltung werfen und das hauptsächlich während des Starts.
https://github.com/torvalds/linux/blob/master/lib/cpumask.c

Wenn ich mir das ansehe frage ich mich eher, wieso das nicht Standard ist.
 
senf.dazu schrieb:
Meine 2 ct:
In einem Multithreading System mußt du die mindestens alle Register der CPUs (inkl. SIMD Register, je virtuellem Kern nicht nur je physischem Prozessorkern) in den Speicher auslagern können. Damit die gerade inaktiven Threads später fortgesetzt werden können.

Das musst Du fuer jeden vom Betriebssystem verwalteten thread (User-thread oder OS-thread) machen (von denen es oft viel mehr gibt als cores/SMT-threads), hat aber nichts mit der Anzahl der cores/SMT-threads zu tun. Die Zahl der vom Betriebssystem verwalteten threads ist auch auf ARM sicher nicht auf 256 begrenzt.
 
  • Gefällt mir
Reaktionen: Piktogramm
Die Gesamtzahl der Threads in einem System wird mit der Zahl der (virtuellen) Cores schon etwas wachsen .. ob die Zahl der Threads je core sich abhängig von der core Zahl ändert das wird eher davon abhängen wieviel und welchen Mix Anwendungen man gleichzeitig laufen läßt.

Das OS Kernel wird wohl selbst wenig Threads beisteuern - aber wohl zumindest die angedeuteten ein bis zwei je (virtuellem) Core ?
Ergänzung ()

mae schrieb:
Das musst Du fuer jeden vom Betriebssystem verwalteten thread (User-thread oder OS-thread) machen (von denen es oft viel mehr gibt als cores/SMT-threads), hat aber nichts mit der Anzahl der cores/SMT-threads zu tun. Die Zahl der vom Betriebssystem verwalteten threads ist auch auf ARM sicher nicht auf 256 begrenzt.
Die Gesamtzahl der Threads in einem System wird mit der Zahl der (virtuellen) Cores schon etwas wachsen .. ob die Zahl der Threads je core sich abhängig von der core Zahl ändert das wird eher davon abhängen wieviel und welchen Mix von (meist ? hochgradig parallelisierten) Anwendungen man gleichzeitig laufen läßt.

Das OS Kernel wird aber wohl selbst wenig Threads beisteuern - aber wohl zumindest die angedeuteten ein bis zwei je (ggf. sogar virtuellem) Core ?
 
Zuletzt bearbeitet:
senf.dazu schrieb:
Die Gesamtzahl der Threads in einem System wird mit der Zahl der (virtuellen) Cores schon etwas wachsen .. ob die Zahl der Threads je core sich abhängig von der core Zahl ändert das wird eher davon abhängen wieviel und welchen Mix Anwendungen man gleichzeitig laufen läßt.

Das OS Kernel wird wohl selbst wenig Threads beisteuern - aber wohl zumindest die angedeuteten ein bis zwei je (virtuellem) Core ?

Auf einem System mit 24 SMT-threads sehe ich ca. 447 Kernel-Threads:

Code:
> ps --ppid 2 -p 2 -o uname,pid,ppid,cmd,cls|wc -l
448

An Kernel-Threads, die offensichtlich einem SMT-Thread zugeordnet sind, sehe ich fuer SMT-Thread 23:

Code:
> ps --ppid 2 -p 2 -o uname,pid,ppid,cmd,cls|grep "/23"
root         129       2 [cpuhp/23]                   TS
root         130       2 [migration/23]               FF
root         131       2 [ksoftirqd/23]               TS
root         133       2 [kworker/23:0H-events_highp  TS
root         327       2 [kworker/23:1H-kblockd]      TS
root     2088856       2 [kworker/23:1-rcu_gp]        TS
root     2096712       2 [kworker/23:2-mm_percpu_wq]  TS

Aber ob die statisch allokiert werden muessen? Naja, ich kann mir schon vorstellen, dass einer davon statisch allokiert werden muss und eben die 8KB braucht, die jeder thread auf Kernel-Ebene braucht.
 
  • Gefällt mir
Reaktionen: Piktogramm
0x8100 schrieb:
der linux-kernel für arm64-cpus ist bis jetzt auf 256 cores beschränkt, was zu wenig für dual- (oder mehr) sockel-systeme mit 192-core cpus von ampere computing ist. es gibt einen patch, womit das limit bald offiziell angehoben wird, selber könnte man das auch jetzt schon machen. bei x86 geht historisch schon länger mehr.

Ich glaube @Firefoxlady wollte genauso wie ich und die Vorredner mehr Infos haben, warum der Kernel bei steigender Kernzahl anwächst, warum der Kernel so klein wie möglich gehalten werden muss und ein paar KB mehr schon schlecht sind usw. Es ging nicht um eine TLDR Zusammenfassung...
 
@aid0nex siehe z.b. https://lemmy.world/comment/5701494 man will den speicherverbrauch auf dem stack so gering wie möglich halten, damit es möglichst keine cache-misses in der cpu gibt, was die leistung drücken würde. es geht nicht um ein paar kB im ram, sondern um den cache in der cpu. und da wir den immer noch in MB messen, sind da 8 kB pro unterstütztem kern relevant.
 
  • Gefällt mir
Reaktionen: konkretor und aid0nex
@0x8100
Wobei die Überlegung arg theoretisch sind. Klar, wenn die CPUmask im Stack liegt, gibt es keine Fragmentierung. Das daraus signifikant mehr Cachtreffer resultieren sollen, halte ich für unwahrscheinlich. Linux rotiert Prozesse mehr oder weniger zufällig zwischen CPU Kernen und die Kernelprozesse sind davon genauso betroffen. Wenn ein solcher Prozess auf einem von 192 bzw. 384 Kernen landet, ist es unwahrscheinlich, dass die CPUmask auch nur in Teilen im L2 dieses Kerns liegt und es ist quasi ausgeschlossen, dass da Relevantes im L1 Cache steht.
Bei AmpereOne bleibt dann noch der SLC mit 64MB auf (bis zu) 192 Kernen oder aber ~340KiB je Kern. Das die relevanten Teile der CPUmask im SLC liegen ist auch nicht wahrscheinlich bei einem System auf dem halbwegs Last ist.

Im Vergleich, Offstack allokiert mit kmalloc für jeden Eintrag in CPUmask mit kmalloc, was eine Fragmentierung erlaubt. Jedoch läuft die Allokation der CPUmask recht weit am Anfang vom Boot und sollte auch ohne Konkurrenz beim Speichermanagement laufen (Multithreading ist schwer, wenn das OS noch nichtmal alle CPU Kerne kennt..). Wenn das System läuft sollte das für Prefetch und Memorymanagement der CPU keinen großen Unterschied machen.
Wenn ich es richtig gelesen habe, ist cpumask_offstack dafür NUMA aware.

Und was die Zugriffsmuster angeht, die CPUmask sollte sowieso recht linear in engen Schleifen von Eintrag zu Eintrag durchschritten werden. Das schafft potentes Prefetch aktueller CPUs so oder so und Caches nutzen da relativ wenig.

Also klar, etwas komplizierter ist Offstack, etwas Overhead gibt es, dadurch dass die cpumask nicht im Stack liegt aber am Ende würde ich da allenfalls für sehr spezifische Fälle geringe einstellige Prozente Leistungsverlust sehen.
 
mae schrieb:
Auf einem System mit 24 SMT-threads sehe ich ca. 447 Kernel-Threads:

Code:
> ps --ppid 2 -p 2 -o uname,pid,ppid,cmd,cls|wc -l
448

An Kernel-Threads, die offensichtlich einem SMT-Thread zugeordnet sind, sehe ich fuer SMT-Thread 23:

Code:
> ps --ppid 2 -p 2 -o uname,pid,ppid,cmd,cls|grep "/23"
root         129       2 [cpuhp/23]                   TS
root         130       2 [migration/23]               FF
root         131       2 [ksoftirqd/23]               TS
root         133       2 [kworker/23:0H-events_highp  TS
root         327       2 [kworker/23:1H-kblockd]      TS
root     2088856       2 [kworker/23:1-rcu_gp]        TS
root     2096712       2 [kworker/23:2-mm_percpu_wq]  TS

Aber ob die statisch allokiert werden muessen? Naja, ich kann mir schon vorstellen, dass einer davon statisch allokiert werden muss und eben die 8KB braucht, die jeder thread auf Kernel-Ebene braucht.
Es geht um den Speicherbedarf von Images ? Und da müssen schätzungsweise alle Threads die der Kernel bis zum Einfrieren für's Image so erstellt hat im Speicher"Image" stehen. Damit man das System allein mit dem Image wieder starten kann. Stichwort Container ?
 
@Piktogramm ich habe mir die technik dafür nicht ausgedacht :) ich kann nur annehmen, dass die kernelentwickler sich was dabei gedacht haben. da wird schon nicht umsonst ein unterschied mittels CPUMASK_OFFSTACK gemacht werden, damit mit man entweder bis zu 8192 kerne unterstützen kann (mit verweis, dass das dann nicht mehr auf dem stack liegt und daher langsamer ist) oder eben bis zu 512 direkt auf dem stack, wobei das default noch niedriger liegt, damit nicht standardmässig unnötig speicher dort belegt wird.
 
Wenn die CPU Geschwindigkeit nicht entscheidend sind sind die ARM Teile ja ganz lustig, aber ich habe zwei Server in Hetzner Cloud gemietet einer ARM der andere AMD, je 2 Cores, der ARM hat 4GB RAM, der AMD 2GB... Sie sollen Hashes von Zips errechnen beides die gleichen Daten der ARM Rechnet seit min 6h, der AMD seit 30min, der AMD hat den ARM schon überholt...
 
Da wäre es interessant, wie sich sowas bei bereits optimierten Systemen verhält. Jetzt wirst Du das nicht extra deshalb machen 😄, aber ein Vergleich bei zB AWS (AMD EPYC vs. Graviton 2 ) und den damit verbundenen Kosten ist da uU interessant.
 
  • Gefällt mir
Reaktionen: AlphaKaninchen
eastcoast_pete schrieb:
Jetzt wirst Du das nicht extra deshalb machen 😄
Mhhh... Warum eigentlich nicht?
Aber nur Komprimieren und Hashsummen brechnen (das ist das wo ich bei Hetzner solche Unterschiede gesehen habe...) ist etwas langweilig, Graviton habe ich bisher nur genutzt um die Zips von der Hetzner Storage Box zu S3 zu verschieben... Interessanter wäre es wahrscheinlich auch gleich Graviton 2 vs Graviton 3 zu machen. Ich finde es auch etwas seltsam das bei meinem Vergleich oben die 2 Ampere Cores kaum ausgelastet sind wärend die AMD bei circa 80% bis 112% sind (also ein Kern am Anschlag) Gut der AMD ist inzwischen mit MD5 fertig umd macht jetzt sha256....

Ich werde nachher einfach mal das größte Zip auf ein Volumen bzw EBS und dann einfach mal auf Ampere und AMD bei Hetzner sowie Graviton 2, AMD und Intel bei AWS machen... nur wie ich das mit dem Zeit messen mache gibt es ein Tool unter Linux mit dem man eine Stoppuhr um einen Befehl legen kann (mein Vorschlag wäre es in einen Systemd Service zu packen, aber der Zeigt CPU Zeit ist, dass das gleiche?)
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: eastcoast_pete
Wenn Du das machst, wären die Ergebnisse es ein gutes Thema für einen Artikel aus der Community. Mich würde es definitiv interessieren!
 
AlphaKaninchen schrieb:
Ich finde es auch etwas seltsam das bei meinem Vergleich oben die 2 Ampere Cores kaum ausgelastet sind wärend die AMD bei circa 80% bis 112% sind (also ein Kern am Anschlag) Gut der AMD ist inzwischen mit MD5 fertig umd macht jetzt sha256....
Wenn du für ein und die selben Daten md5 und sha256 willst, ich würde probieren da beide Hashsummen auf einen Schlag berechnen zu lassen, anstatt die Daten mehrmals vom Festspeicher zu lesen.dd if=foo.bar | tee >(md5sum >md5.txt) | sha256sum >sha256.txt. Das langsamste ist ja meist iowait und das kannst du so umgehen, zudem laufen die meisten Hashfunktionen eh nur auf einem Kern und du hast so gleich sehr simpel Nebenläufigkeit implementiert.

Und wenn die Kerne bei den Ampere Altra CPU kaum ausgelastet sind. Da wäre dann mal zu schauen wieso dem so ist. Massig iowait? Überbuchtes System mit recht viel "steal"?

Ansonsten, die Altras sind ARM Neoverse V1 bzw. leicht aufgebohrte A76 Kerne (die auch im Raspi5 stecken). Die Kerne sind nicht schlecht, aber den Designs merkt man an, dass sie Energieeffizienz vor Durchsatz priorisiert wurde: https://chipsandcheese.com/2021/08/05/neoverse-n1-vs-zen-2-arm-in-practice/
 
Genau wegen solchen Artikeln ist die generelle Meinung von Linux so schlecht...
Die Fakten stimmen ja, aber es wird so dargestellt, als hätte nur Linux dieses Problem und jedes andere OS könnte das mit links, obwohl es viel schlechter wäre.
 
Piktogramm schrieb:
Und wenn die Kerne bei den Ampere Altra CPU kaum ausgelastet sind. Da wäre dann mal zu schauen wieso dem so ist. Massig iowait? Überbuchtes System mit recht viel "steal"?
Ich errechne den Wert mit rclones hashsum ---download Option, wenn ich es wirklich nur zwecks Vergleich mache würde ich es vom Lokalen Speicher machen...

Das absurde ist eben das der AMD eigentlich bei allem im Nachteil ist, weniger RAM, Server in Helsinki und Storage Box in Falkenstein.

Was ich noch überlegt habe, kann es sein das rclones arch64 Version einfach weniger Optimiert ist, also z.B. SIMD nicht nutzt?

Ich hatte das auch schon als ich die Daten mit 7zip komprimiert habe damals wollte ich erst alles auf Ampere machen am Ende habe ich es auf Ampere heruntergeladen das Volumen " umgeklemmt" und auf AMD Komprimiert....

Überbuchung kann man schlecht herausfinden oder? Aber müsste Hetzner dann AMD nicht genauso überbuchen, ich nehme ja nicht die dediziert Option bei den AMD sondern die normalen...
Ergänzung ()

Egaaal schrieb:
Genau wegen solchen Artikeln ist die generelle Meinung von Linux so schlecht...
Die Fakten stimmen ja, aber es wird so dargestellt, als hätte nur Linux dieses Problem und jedes andere OS könnte das mit links, obwohl es viel schlechter wäre.
Eigentlich sollten das mMn die Distros nach Ausrichtung entscheiden, bei OpenWRT oder Android macht es z.B. Sinn wenn die Zahl klein ist, bei einer Server Distro sind 512 oder gar 1024 schon angebracht (insbesondere bei Langen Releas Zyclen)

Ampere möchte aber nicht mit jedem einzeln Diskutieren, und hofft das es einfach von Mainline übernommen wird.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Egaaal
@AlphaKaninchen
Also wie genau rclones arbeitet weiß ich nicht. Wenn es aber darum geht großartig Daten zu laden, dann werden da beim berechnen von Hashes Latenzen der Netzwerkverbindung fast keine Rolle spielen, da da sowieso prefetch über sequentielle Datenströme betrieben wird.

Die Optimierung von rclones. Da ist fast alles in Go geschrieben, und die aktuellen Versionen von Go haben auf ARM meines Wissens keine Nachteile im Vergleich zu x86. Zudem die eigentlichen Hashfunktionen aus der Standardlib vom Goprojekt stammt. Für MD5 gibt es in der Lib keinen SIMD Zweig, weder für AMD64 noch AArch64, aber für beide handgeklöppeltes Assembly. Für beide Architekturen erscheint mir das gleichwertig, wenn auch der x86Code wesentlich hübscher ist (ließt sich Imho viel besser). Für Sha256 unterscheidet die Lib für AMD64 nach AVX2 + BMI und nutzt dann AVX2 Pfade, oder aber bevorzugt wenn vorhanden die Sha2 Erweiterung der x86er. Für Aarch64 wird nur geprüft, ob die sha256 Cryptoerweiterung verfügbar ist, die bei den Altras aber vorhanden sein müsste. Am Ram liegt es tendenziell auch nicht, Hashfunktionen + Daten auf denen gerade gerechnet wird passen in wenige Kilobyte, da kann man davon ausgehen, dass wenn die Daten einmal vom I/O geliefert wurden, dass der Spaß überwiegend im L1 Cache stattfindet.
Was bleibt sind die Unterschiede zwischen den CPUs. Ampere Altra hat 2x 128breite SIMD Pipelines und Zen2, Zen3 hat zwei 256breite Einheiten. Wobei AMDs Zen allgemein glaube deutlich besser ausgestellt ist, was Load/Store angeht (wie gesagt, AMDs Neoverse sieht man noch arg an, dass da Effizienz und kompaktes Design wichtig waren).


Überbuchen herauszufrinden ist je nach Virtualisierunslösung aufwendig. Wenn der Anbieter so nett ist und KVM (Kernel Virtual Machine) nutzt, dann sehen die Gastsystem CPU-steal.
Ergänzung ()

Nachtrag @AlphaKaninchen
Beim Tab schließen ist mir gerade noch was ins Auge gefallen. Sha256 für ARM64 derart geschrieben, dass das optimierte Aarch64 Assembly generell für Neon geschrieben ist und nur prüft ob die optionale Cryptoerweiterung für Sha256 vorhanden ist und entsprechend verzweigt. Erst wenn man Go für ARM v5, v6 oder v7 baut, würde Sha256 auf ARM ohne Optimierung auskommen müssen und generischen, in Go geschriebenen Code nutzen.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: AlphaKaninchen
Zurück
Oben