Auf BIOS 303 fällt die GPU des ASUS ProArt P16 nie in den 754-MHz-Zustand, den NVIDIA open-gpu-kernel-modules #1521 beschreibt. Nach einem Boost von etwa 15 Sekunden pendelt sie sich auf das Budget ein, das die Thermal-Policy des ASUS Embedded Controllers (EC) vorgibt: 22 W in Silent, 32 W in Balanced, 55 W in Performance.
Der Stock-Kernel von Omarchy hat auf ARM64 keinen ASUS-WMI-Treiber. Er kann die Policy also nicht ändern und bleibt beim Balanced-Default des EC mit 32 W. Der NVIDIA-Treiber setzt diese Grenze nicht.
Testsystem
| Komponente | Stand |
|---|---|
| Gerät | ASUS ProArt P16 H7607BA |
| BIOS / EC | 303 (2026-09-22) / EC 3.3 |
| GPU | N1X, 10de:2e03, VBIOS 9A.0B.35.00.04 |
| Kernel | 7.3.0-41-omarchy (Stock) und 7.3.0-41-omarchy-p16 |
| NVIDIA-Treiber | 615.78.08 und 620.70.06 |
| Gemessen | 2026-11-09 |
Ein Schalter setzt das Budget
Die Werte stammen aus 180 s FP32-GEMM, jeweils der Median von Sekunde 60 bis 175.
| Policy | DEVS-Wert | Dauerleistung | SM-Takt | FP32 |
|---|---|---|---|---|
| Silent | v=2 | 22 W | 1124 MHz | 9,2 TFLOP/s |
| Balanced | v=0 | 32 W | 1540 MHz | 12,4 TFLOP/s |
| Performance | v=1 | 55 W | 1979 MHz | 15,9 TFLOP/s |
Balanced ist der Default des EC und das, was der Stock-Kernel bekommt. Ich habe Balanced auch als meinen Default gewählt. Performance boostet etwa 25 s lang auf 72 W, die GPU erreicht dabei maximal 80 °C.
Jeder Lauf startet nach einer Abkühlphase. nvidia-smi liefert alle 500 ms einen Messwert, die Grafik zeigt den Mittelwert pro Sekunde. Jede Policy boostet zuerst und pendelt sich dann ein. Die Stock-Kernel-Kurve (gestrichelt) liegt auf der Balanced-Kurve: Ohne ASUS-Treiber bleibt der EC in Balanced.
| Lauf | Kernel | Policy | Spitze W | Dauer W | SM MHz | GFLOP/s | GPU max °C |
|---|---|---|---|---|---|---|---|
| h2 | p16 | Performance | 71,7 | 55,3 | 1979 | 15925 | 80 |
| h1 | p16 | Balanced | 50,2 | 32,1 | 1540 | 12425 | 73 |
| c1 | Stock | (EC-Default) | 48,0 | 31,6 | 1530 | 12345 | 72 |
| f3 | p16 | Silent | 40,3 | 22,4 | 1124 | 9158 | 73 |
Policy-Wechsel unter Last
Um zu belegen, welcher Aufruf das Budget setzt, habe ich den P16-Kernel mit gesperrtem asus_nb_wmi gebootet. Dann habe ich einzelne ASUS-WMI-Aufrufe per acpi_call von Hand abgesetzt, während der GEMM lief.
Der Lauf startete in Performance, weil der vorige Boot diesen Modus gesetzt hatte. Der EC behält seinen Modus über Warmstarts. Silent senkt die GPU innerhalb von etwa 4 Sekunden auf 22 W. Balanced bringt sie auf 31,5 W. Der vorher getestete INIT-Aufruf (Lauf g1) änderte nichts.
Die Leistung stellt sich nach jedem Aufruf innerhalb von Sekunden ein. Der SM-Takt folgt ihr: etwa 2150 MHz im Boost, 1110 MHz in Silent und 1510 MHz in Balanced.
Wie ein Profilwechsel beim EC ankommt
powerprofilesctl set balanced: power-profiles-daemon schreibt/sys/firmware/acpi/platform_profile.asus-nb-wmi→throttle_thermal_policy: Das gibt es nur auf dem P16-Kernel. Die ASUS-WMI-Unterstützung für ARM64 stammt aus omarchy-pkgs PR 1958 (Patch 9100).\_SB.ATKD.WMNB→DEVS(0x00120075, v): v = 0 ist Balanced, 1 Performance, 2 Silent.DSTSliefert immer 0x00010003. Die Firmware meldet den aktuellen Modus also nie.WEBC(0x11, mode): Der EC-Befehl nimmt Mode 1 für Balanced, 4 für Performance und 2 für Silent. Er schreibt außerdem die EC-Register C4/C5/CC/CD und setzt\_SB.THPL. Danach erzwingt der EC das GPU-Budget.
Ohne ASUS-Treiber (Stock-Kernel) funktioniert derselbe Aufruf über acpi_call mit einem 20-Byte-Puffer. Das ist nur für Tests gedacht und kein Teil meines Setups:
\_SB.ATKD.WMNB 0 0x53564544 {0x75,0,0x12,0, v, 0…}
# 0x53564544 = "DEVS" 0x00120075 = throttle_thermal_policy
INIT setzt nur \_SB.ATKP = 1. Das schaltet Hotkey-Benachrichtigungen frei und hat keinen Einfluss auf die Leistung.
Was die 32-W-Grenze nicht verschoben hat
Bevor ich den ASUS-Kernel ausprobiert habe, habe ich auf dem Stock-Kernel jede Änderung auf NVIDIA-Seite und an der Stromversorgung getestet. Jeder Lauf zeigt dasselbe Bild: etwa 48 bis 50 W bei rund 2000 MHz für etwa 15 s, danach eine flache Software-Power-Cap (Grund 0x4) bei 32 bis 33 W.
| Lauf | Treiber | Last | Bedingung | Grund | SM MHz | GPU W | GFLOP/s (Median) |
|---|---|---|---|---|---|---|---|
| b1 | 615 | FP32 | Netzteil, ppd performance | 0x4 | 1586 | 33,1 | 12954 |
| b3 | 615 | FP32 | Netzteil, ppd balanced | 0x4 | 1573 | 33,0 | 12827 |
| b2 | 615 | BF16 | Netzteil | 0x400 | 1891 | 30,3 | 67040 |
| c1 | 620 | FP32 | Netzteil | 0x4 | 1540 | 31,7 | 12421 |
| c2 | 620 | BF16 | Netzteil | 0x400 | 1846 | 29,3 | 65684 |
| d1 | 620 | FP32 | Netzteil, RMSkipACPIBattCap=1 | 0x4 | 1547 | 32,3 | 12487 |
| e1 | 620 | FP32 | Akku, RMSkipACPIBattCap=1 | 0x4 | 1560 | 32,4 | 12596 |
| e2 | 620 | FP32 | Akku, Netzteil nach 60 s eingesteckt | 0x4 | ~1540 | 32,3 | 12539 |
Die Werte sind Mediane aller Samples mit mindestens 50 % GPU-Auslastung. Die BF16-Läufe treffen einen anderen Limiter (0x400) bei etwas geringerer Leistung. Das Profil von power-profiles-daemon wirkt auf dem Stock-Kernel nicht, weil es dort nur die CPU steuert (nvidia_rtx_spark).
Vergleich mit #1521
Die Reporter im Issue nutzten BIOS 300, mein Gerät läuft mit BIOS 303.
| Punkt | Issue (BIOS 300) | Hier (BIOS 303) | Ergebnis |
|---|---|---|---|
| 747–754 MHz P4-Cap unter Last (0x400) | Ja (kopierte DSDT oder vor einem EC-Reset) | Nie gesehen: 615 und 620, Netzteil, Akku, Umstecken | Anders |
NPCF _DSM antwortet nur auf Rev 0x300 | Ja | Ja. Ein statischer Stub: f1 ein fester 128-Byte-Blob, f2/f3 sechs Null-Bytes, kein Notify | Gleich |
| Power Limits N/A, Dynamic Boost “Not Supported” | Ja | Ja | Gleich |
| nvidia-powerd 615: “SBIOS support not found for NVPCF GET_SUPPORTED” | Ja | Ja | Gleich |
| nvidia-powerd 620 beendet sich nach ~0,25 s | Ja | Ja, gleicher Binary-Hash | Gleich |
| Dauerleistung im schnellen Zustand | 47,6–61,6 W (seankd3, ASUS-WMI-Kernel, mehrere Änderungen gleichzeitig) | 32 W Stock, 55 W mit Performance-Policy | Erklärt |
RMSkipACPIBattCap=1 | Zusammen mit zwei anderen Änderungen genutzt | Allein: keine Wirkung, weder am Netzteil noch auf Akku. Nicht im offenen RM-Quellcode, aber als String in der GSP-Firmware | Neu |
| Akku gegen Netzteil | Akku hob die 754-MHz-Cap nicht auf | Akku = Netzteil (gleiche 32 W) | Neu |
| Umstecken unter Last | HP: kurz 1625–1781 MHz | 1 s Einbruch auf 689 MHz, 1 s bei 40,8 W, dann wieder 32 W | Anders |
Tickrate von %clock64 | 190 M Ticks/s an der Cap (als SM-Takt gelesen, später zurückgezogen) | 2490–2590 M Ticks/s, egal ob der SM mit 1500, 1900 oder 2150 MHz läuft. Auf N1X ist das also nicht der SM-Takt | Neu |
Was die Policy für LLM-Arbeit bedeutet
Getestet mit llama.cpp a4d4f2f, CUDA 13.4, P16-Kernel und Treiber 620.70.06.
Kurze Benchmarks enden innerhalb des Boost-Fensters. Dort sehen Balanced und Performance fast gleich aus. Erst Dauerlast zeigt den Unterschied. Die Prompt-Verarbeitung ist rechenintensiv und gewinnt mit Performance etwa 16 %. Die Token-Generierung hängt an der Speicherbandbreite (etwa 245 GB/s der ~273 GB/s LPDDR5X-Spitze). Sie gewinnt nur 3,5 %, bei fast doppelter Leistungsaufnahme.
Grundlage ist der Durchsatz am Ende des Laufs geteilt durch die GPU-Leistung am Ende des Laufs (jeweils das letzte Viertel eines Laufs von ~90 bis 140 s). In Balanced schafft die Generierung 1,9-mal so viel Arbeit pro Joule und ist nur 3,5 % langsamer.
Qwen3.6-35B-A3B (MoE) unter Dauerlast:
| Test | Policy | Dauer | tok/s Mittel | tok/s erstes → letztes ¼ | GPU W erstes → letztes ¼ | SM MHz erstes → letztes ¼ | T max |
|---|---|---|---|---|---|---|---|
| pp4096 × 60 | Performance | 85 s | 2895,5 | 2952,6 → 2865,7 | 60,2 → 49,5 | 2431 → 2190 | 74 °C |
| pp4096 × 60 | Balanced | 97 s | 2546,3 | 2712,6 → 2466,1 | 42,0 → 26,3 | 2099 → 1586 | 72 °C |
| tg2048 × 5 | Performance | 134 s | 76,3 | 76,6 → 76,2 | 51,6 → 46,6 | 2483 → 2392 | 78 °C |
| tg2048 × 5 | Balanced | 138 s | 74,0 | 75,3 → 73,6 | 24,8 → 24,0 | 1911 → 1820 | 73 °C |
Zum Vergleich kurze llama-bench-Läufe (pp512 / tg128, 3 Wiederholungen, innerhalb des Boost-Fensters):
| Modell | Policy | pp512 tok/s | tg128 tok/s | GPU W Median | SM MHz Median |
|---|---|---|---|---|---|
| Qwen3-32B Q4_K_M (dense, 18,4 GiB) | Performance | 787,6 ± 7,9 | 12,40 ± 0,01 | 54,0 | 2460 |
| Qwen3-32B Q4_K_M | Balanced | 723,7 ± 3,2 | 12,09 ± 0,21 | 23,4 | 1729 |
| Qwen3.6-35B-A3B UD-Q4_K_M (MoE, 20,6 GiB) | Performance | 3024,0 ± 48,0 | 77,80 ± 0,01 | 48,9 | 2528 |
| Qwen3.6-35B-A3B UD-Q4_K_M | Balanced | 2906,4 ± 36,8 | 77,45 ± 0,10 | 41,9 | 2411 |
Nebenbefunde
- power-profiles-daemon kann vor
asus-nb-wmistarten. Er hängt sich dann an einen Platzhalter-Treiber und zeigt ein Profil an, das er nie an den EC weitergibt. Ein Drop-in lässt ppd jetzt aufplatform_profilewarten. Eine udev-Regel startet ppd neu, falls sich der ASUS-Treiber spät registriert. - Der EC merkt sich seinen Modus über Warmstarts. Ein Boot ganz ohne ASUS-Treiber lief trotzdem mit 55 W, weil der vorige Boot Performance gesetzt hatte (Lauf g0).
%clock64ist auf N1X nicht der SM-Takt. Er tickt mit etwa 2,5 GHz, egal wie schnell der SM läuft. Die frühere Deutung als Taktmessung in #1521 wurde zurückgezogen.- NPCF liefert keine Budgetdaten, die der NVIDIA-RM nutzen könnte, und 620.70.06 behandelt
_DSMRev 0x300 bereits. In open-gpu-kernel-modules gibt es nichts zu patchen. - Die Temperaturen blieben innerhalb der Watchdog-Grenzen (Abbruch bei GPU ≥ 87 °C, irgendeiner Zone ≥ 95 °C oder > 1 °C/s ab 75 °C). Die GPU erreichte in Performance maximal 81 °C, die ACPI-Zonen 86 °C. Der Watchdog griff einmal: Lauf g1 stoppte nach 70 s, als eine ACPI-Zone 95 °C erreichte.
Meine Konfiguration
Balanced ist der Default (Entscheidung vom 2026-11-09). Performance bringt 16 % mehr bei dauerhafter Prompt-Verarbeitung und fast nichts bei der Generierung. Dafür verdoppelt sich die GPU-Leistung, das Gerät wird heißer und lauter. Ein anderer N1X-Besitzer meldete eine thermische Notabschaltung, nachdem er die Takte freigeschaltet hatte.
Bei Bedarf wechsle ich mit powerprofilesctl set performance. ppd speichert die Wahl und stellt sie nach einem Neustart wieder her.
Boot-Stack:
- Default:
linux-omarchy-p167.3.0-41 (ASUS WMI für ARM64) plusnvidia-open-dkms620.70.06 mit den 7 Omarchy-N1X-Patches - Fallbacks: Stock
linux-omarchyund ein Limine-Snapshot-Eintrag mit 615.78.08 - Nach Kernel-Updates prüfe ich
default_entryin Limine, weil neue Einträge die Nummerierung verschieben können
Die Startreihenfolge für power-profiles-daemon:
# /etc/systemd/system/power-profiles-daemon.service.d/10-n1x-wait-platform-profile.conf
[Service]
ExecStartPre=/bin/sh -c 'for i in $(seq 40); do [ -e /sys/firmware/acpi/platform_profile ] && exit 0; sleep 0.5; done; exit 0'
# /etc/udev/rules.d/90-n1x-asus-platform-profile.rules
ACTION=="add", SUBSYSTEM=="platform-profile", ATTR{name}=="asus-wmi", \
RUN+="/usr/bin/systemctl --no-block try-restart power-profiles-daemon.service"
Eine Korrektur
Mein erster Kommentar in #1521 behauptete, der Sprung von 32 auf 55 W käme allein vom geladenen ASUS-Treiber. Das war falsch. In diesem Lauf (f1) hatte power-profiles-daemon die Policy mitten im Lauf auf Performance gestellt. Der ASUS-Treiber selbst setzt beim Laden Balanced, also 32 W. Die Korrektur habe ich noch am selben Nachmittag gepostet.
Methode
n1xprobe (CUDA 13.4) führt cuBLAS GemmEx mit n=4096 in FP32 oder BF16 aus und meldet GFLOP/s pro Sekunde. Ein Python-Skript fragt nvidia-smi alle 500 ms ab (P-State, SM-Takt, Throttle-Gründe, Leistung, Temperatur) und betreibt den thermischen Watchdog. Jeder Lauf dauert 180 s. Zwischen den Läufen liegen mindestens 60 s Abkühlung auf unter 55 °C. Alle Tests liefen auf einer Wegwerf-Installation von Omarchy 4.5 (edge) auf einer Ersatz-SSD, mit der nativen DSDT der Firmware.
Quellen
- Befunde: Kommentar in #1521 und die Korrektur
- Rohdaten, Probe-Quellcode und NPCF-Disassembly: Gist
- Zweiter Teil: Lokale LLM-Inferenz auf dem N1X: vLLM, llama.cpp und Strata