Praktischer Leitfaden, um auf gewöhnlichem Windows so nah wie möglich an Soft Real-Time heranzukommen

· · Windows-Entwicklung, Soft Real-Time, Design, Messung

Wenn man unter Windows periodische Verarbeitung, Audio-Verarbeitung, Video-Verarbeitung, Messung oder Anlagensteuerung baut – also Prozesse, bei denen „zu spät“ ein Problem ist –, entsteht schnell der Eindruck, „das dürfte unter Windows schwierig sein“. Dieser Eindruck ist halb richtig und halb falsch: Windows ist kein Hard-Real-Time-Betriebssystem, aber wenn Sie Entwurf, Implementierung, Messung und Betrieb sauber durcharbeiten, lässt es sich als Soft Real-Time in einen durchaus praxistauglichen Zustand bringen.

In diesem Artikel geht es um gewöhnliches Windows 10 / 11, ohne die Voraussetzung besonderer RTOS-Erweiterungen, eigener Kernel-Treiber oder dedizierter Controller. Es ist ein praxisnahes Thema: Wie weit lassen sich Latenz und Jitter mit einer User-Mode-App auf einem gewöhnlichen Desktop- oder Notebook-PC herunterdrücken? Bei Audio, Video, periodischer Steuerung und Datenerfassung unterscheiden sich die Details, aber die typischen Problemstellen sind weitgehend gleich, weshalb wir diese gemeinsamen Punkte diesmal in Form einer Checkliste zusammengefasst haben.

Zielgruppe und die Sprache der Codebeispiele

Dieser Artikel richtet sich an Entwickler, die unter Windows Prozesse bauen, bei denen „zu spät“ ein Problem ist (periodische Steuerung, Audio/Video, Messung, Anlagensteuerung). Vorausgesetzt wird Entwicklung im User-Mode; die Implementierung von Kernel-Mode-Treibern liegt außerhalb des Rahmens.

Die Sprache der Codebeispiele teilt sich wie folgt auf.

Inhalt Sprache Ort
Teile, die Win32-APIs direkt aufrufen – periodische Schleife, MMCSS, Power-QoS C++ (Win32) 4.1, 4.3, 4.5
Dieselben Win32-APIs, aus C# aufgerufen C# (P/Invoke) 4.5
Zeitmessung, GC, Hinweise zu Allokationen .NET (C#) „.NET-seitige Prüfpunkte“ in 4.4, 5.2

Die Ursachenanalyse bis Kapitel 3 und der Hauptteil der Checkliste in Kapitel 4 sind sprachunabhängig. Wer ausschließlich C# verwendet, kann den C++-Code einfach als Erklärung lesen, „welche API in welcher Reihenfolge aufgerufen wird“ – das genügt.

Inhaltsverzeichnis

  1. Zuerst das Fazit (in einem Satz)
    • 1.1. Kurzübersicht nach Periodenbereich (wo Sie einsteigen sollten)
  2. Was „Soft Real-Time“ auf gewöhnlichem Windows bedeutet
    • 2.1. Was dieser Artikel mit „gewöhnlichem Windows“ meint
    • 2.2. Was möglich ist und ab wo es schwierig wird
    • 2.3. Kurz vorab: die Begriffe
  3. Die Hauptursachen für Latenz und Jitter
    • 3.1. Scheduler und Priorität
    • 3.2. DPC / ISR und Treiber
    • 3.3. Page Faults und Speicher
    • 3.4. Timer-Auflösung und Energieverwaltung
    • 3.5. Core-Wechsel und Wärme
  4. Praktische Checkliste, um Verzögerungen auf gewöhnlichem Windows zu reduzieren
    • 4.1. Periodische Schleife und Wartemethode
    • 4.2. fast path / slow path und Queue fester Länge
    • 4.3. Priorität / MMCSS / Background Mode
    • 4.4. Speicher / GC / Erstkosten
    • 4.5. Energieeinstellungen / EcoQoS / Timer-Auflösung
    • 4.6. CPU-Platzierung / Core-Wechsel / Wärme
    • 4.7. Treiber / DPC / ISR / externe Störungen isolieren
  5. Messung und Bewertung
    • 5.1. Was aufgezeichnet werden sollte
    • 5.2. Wie p99 / p99.9 / max zu lesen sind
    • 5.3. Womit gemessen wird
    • 5.4. Die Vorgehensweise beim Testen
  6. Grobe Entscheidungshilfe
  7. Zusammenfassung
  8. Quellen

1. Zuerst das Fazit (in einem Satz)

  • Was auf gewöhnlichem Windows angestrebt wird, ist keine Hard-Real-Time-Garantie, sondern eine Soft-Real-Time-Konfiguration, die „selten zu spät kommt und dabei nicht zusammenbricht, wenn es doch passiert“.
  • Am wirkungsvollsten ist es, den Hot Path kurz, fest in der Länge und nicht-blockierend zu halten.
  • Trennen Sie den fast path (Erfassung / Steuerung) vom slow path (Speicherung / Kommunikation / UI) und verbinden Sie beide über eine Queue fester Länge.
  • Die periodische Schleife läuft nicht auf Sleep(1) verlassen, sondern über eine absolute Deadline.
  • Bei kontinuierlichen Streams wie Audio oder Video prüfen Sie zuerst MMCSS.
  • Für die Zeitmessung verwenden Sie QueryPerformanceCounter (QPC), unter .NET Stopwatch.
  • Beim Warten bevorzugen Sie ein Geräte-Ereignis oder einen hochauflösenden waitable timer (wartbaren Timer).
  • timeBeginPeriod verwenden Sie nur, solange es nötig ist. Entwerfen Sie nicht mit der Annahme, dass es dauerhaft aktiv ist.
  • Im laufenden Betrieb zahlen sich AC-Stromversorgung / der Energiemodus / der Umgang mit EcoQoS / das Aufräumen der Hintergrundlast aus.
  • Bewerten Sie nicht nur den Mittelwert, sondern p99 (die Schwelle, ab der bei 100 Messungen der eine langsamste Wert sichtbar wird) / p99.9 / max / die Anzahl der Misses / DPC / ISR / Page Faults / die Queue-Tiefe.

Kurz gesagt: Auf gewöhnlichem Windows wirkt es stärker, die Gründe für Verzögerungen durch den Entwurf zu reduzieren, als die Priorität zu erhöhen. Priorität und Energieeinstellungen sind wichtig, aber allein schaffen sie noch keine Stabilität.

1.1. Kurzübersicht nach Periodenbereich (wo Sie einsteigen sollten)

Da der Artikel lang ist, stellen wir die Kurzübersicht vorab, damit Sie nur die für Ihren Fall passende Zeile lesen können. Der Inhalt, der früher am Ende (Kapitel 6) stand, wurde hierher vorgezogen.

Periode / Anforderung Zuerst aufzubauende Struktur Schwerpunkt-Abschnitte
Klasse 10–20 ms, gelegentliche Schwankungen sind verkraftbar Trennung von fast path / slow path, Queue fester Länge, normale bis leicht erhöhte Priorität, ereignisgesteuert. Das reicht oft schon aus 4.1, 4.2
Klasse 1–5 ms, soll durchgehend Schritt halten Zusätzlich: allokationsfreier Hot Path, dedizierter Thread, MMCSS oder sorgfältige Prioritätsanpassung, hochauflösender waitable timer, AC-Stromversorgung und überarbeitete Energieeinstellungen 4.1–4.5
Nähert sich unter 1 ms, darf auch bei langer Laufzeit und hoher Last nichts verfehlen Mit User-Mode allein auf gewöhnlichem Windows ziemlich schwierig. Zuerst einen Entwurf prüfen, der den kritischen Teil an einen anderen Ort auslagert (geräteseitige Firmware, dedizierter Controller, FPGA, RTOS) 2.2, 6
Soll alles gleichzeitig mit GUI / Logging / Kommunikation / DB unterbringen Nicht alles in „einen Prozess, eine Schleife“ packen, sondern Zuständigkeiten trennen. Belange der nachgelagerten Stufe brechen leicht die Deadline der vorgelagerten Stufe 4.2, 4.3, 6

Die Ursachenanalyse und die Vorgehensweise bei der Messung sind unabhängig vom Periodenbereich gleich (Kapitel 3 und 5).

2. Was „Soft Real-Time“ auf gewöhnlichem Windows bedeutet

2.1. Was dieser Artikel mit „gewöhnlichem Windows“ meint

Mit gewöhnlichem Windows ist hier grob Folgendes gemeint.

  • Ein typischer Windows 10/11 Desktop- oder Notebook-PC
  • Keine eigenen RTOS-Erweiterungen
  • Keine eigene Kernel-Mode-Treiberentwicklung
  • Eine gewöhnliche User-Mode-App
  • Abstimmung über gängige Windows-APIs und -Einstellungen

Es geht also nicht darum, „ein komplettes Spezialgerät für die Echtzeitsteuerung zu bauen“, sondern darum, „wie weit sich das auf einem gewöhnlichen Windows-PC realistisch ausreizen lässt“.

Gewöhnlicher Windows 10 / 11 PCUser-Mode-AppSoft Real-Time anstrebenLatenz niedrig haltenJitter klein haltenDeadline Misses beobachten und Zusammenbrüche vermeidenNull Terminverletzungen garantieren wollenRTOS / dedizierter Controller / FPGA / geräteseitige Verarbeitung

2.2. Was möglich ist und ab wo es schwierig wird

Auch auf gewöhnlichem Windows lässt sich für Verarbeitung wie die folgende durchaus realistisch ein Zustand herstellen, der „selten zu spät kommt“.

  • Periodische Verarbeitung von wenigen Millisekunden bis zu einigen Dutzend Millisekunden
  • Pufferbasiertes Audio / Video
  • Sensorerfassung und Regelschleifen
  • Soft-SPS-artige Verarbeitung mit fester Periode
  • Eine Low-Latency-Pipeline, die auf einem eigenen Thread getrennt von der UI läuft

Allerdings bedeutet „geht“ hier nicht, dass sich gelegentliche Latenzspitzen vollständig auf null bringen lassen. Angestrebt wird lediglich dieser Zustand:

  • Die Latenz im Normalfall niedrig halten
  • Den Jitter klein halten
  • Nicht zusammenbrechen, wenn gelegentlich eine Deadline verfehlt wird
  • Die Tatsache, dass eine Deadline verfehlt wurde, beobachten können

Umgekehrt wird es mit User-Mode allein auf gewöhnlichem Windows ziemlich schwierig, Anforderungen wie die folgenden zu erfüllen.

  • Null Terminverletzungen garantieren
  • Wenige hundert Mikrosekunden oder weniger über lange Zeit stabil einhalten
  • Mit einer schweren GUI, Netzwerk und Storage koexistieren
  • Es im Batteriebetrieb oder unter Energiespar-Priorität durchziehen
  • Auch Spitzen, die von Treibern oder Geräten stammen, nicht tolerieren

Hier ist es sicherer, auch in Betracht zu ziehen, nur den wirklich zeitkritischen Teil an geräteseitige Firmware, einen dedizierten Controller, ein FPGA oder ein RTOS auszulagern.

2.3. Kurz vorab: die Begriffe

Klären wir zuerst die in diesem Artikel verwendeten Begriffe.

Begriff In einem Satz Praktische Einordnung
Soft Real-Time Gelegentliche Verzögerungen sind möglich, aber der Ansatz zielt darauf, sie klein zu halten und nicht daran zu zerbrechen Das ist es, was man auf gewöhnlichem Windows zuerst anstrebt
Hard Real-Time Eine Welt, in der null Terminverletzungen garantiert werden müssen Kein Ziel, das sich mit User-Mode allein auf gewöhnlichem Windows anstreben lässt
Jitter Schwankung der Periode oder der Antwortzeit Auch bei gutem Mittelwert bedeutet großer Jitter Instabilität im Betrieb
Deadline Miss Verarbeitung, die nicht bis zum geplanten Zeitpunkt fertig wird Nicht verstecken – zählen und loggen
p99 / p99.9 Kennzahlen, die die langsame Seite der Verteilung betrachten p99 ist „die Schwelle, ab der bei 100 Messungen der eine langsamste Wert sichtbar wird“
DPC / ISR Kernel-seitige Verarbeitung rund um Treiber und Interrupts Dauert sie lange, muss der User-Mode-Thread warten
MMCSS Der Windows-Mechanismus, der CPU-Zeit an zeitkritische Verarbeitung wie Audio/Video verteilt Stark bei Verarbeitung, deren Puffer nicht leerlaufen darf
QPC Steht für QueryPerformanceCounter Grundlage der Messung verstrichener Zeit – ein hochauflösender Zähler, keine Wanduhr
waitable timer (wartbarer Timer) Ein Kernel-Objekt, das zu einem festgelegten Zeitpunkt signalisiert wird. Mit CREATE_WAITABLE_TIMER_HIGH_RESOLUTION bei CreateWaitableTimerExW entsteht die hochauflösende Variante Besser als Grundlage für periodisches Warten geeignet als Sleep (4.1)
EcoQoS Ein Zustand, der als „Energiesparen darf priorisiert werden“ eingestuft ist. Dabei wird die CPU-Frequenz gesenkt oder die Arbeit auf energieeffiziente Cores verlagert Bei zeitkritischer Verarbeitung vermeiden. Ohne explizite Angabe schätzt das Betriebssystem automatisch (4.5)
IGNORE_TIMER_RESOLUTION Die Angabe, dass die Timer-Auflösungsanforderung eines Prozesses ignoriert werden darf (PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION) Ist dies aktiv, verpufft die Wirkung von timeBeginPeriod. Unter Windows 11 kann es automatisch greifen, sobald das Fenster verdeckt ist (4.5)
CPU Sets Ein Mechanismus, der Threads oder Prozessen weich vorgibt: „Bitte auf dieser Core-Gruppe laufen“ Zuerst ausprobieren, bevor man auf eine feste Core-Zuweisung geht (4.6)
ETW / WPR / WPA Die Windows-Standard-Trace-Infrastruktur (ETW) mit ihrem Aufzeichnungswerkzeug (WPR) und der Analyse-GUI (WPA) Wird verwendet, um Context Switches, DPC/ISR und Page Faults zu untersuchen (5.3)
LatencyMon Ein Drittanbieter-Tool, um treiberbedingte Latenzen zu betrachten Zeigt die Ausführungszeit von DPC/ISR nach Treiber sortiert, um Verdächtige einzugrenzen (5.3)

3. Die Hauptursachen für Latenz und Jitter

Die Gründe, warum periodische Verarbeitung auf gewöhnlichem Windows zu spät kommt, laufen meist auf einen der Punkte in diesem Diagramm hinaus.

Periodische Verarbeitung kommt zu spätScheduler / PrioritätDPC / ISR / TreiberPage Fault / SpeicherTimer-Auflösung / EnergieverwaltungCore-Wechsel / Wärme

3.1. Scheduler und Priorität

Bei Windows-Threads bestimmt die Priorität die Ausführungsreihenfolge. Bei gleicher Priorität läuft es Round-Robin, und sobald ein Thread mit höherer Priorität ausführbar wird, wird ein Thread mit niedrigerer Priorität verdrängt.

Das heißt: Auch wenn Sie den periodischen Thread sorgfältig schreiben, ist es völlig normal, dass Folgendes zuerst läuft:

  • Ein anderer Thread
  • Ein anderer Prozess
  • Interne Verarbeitung des Betriebssystems
  • Sicherheitsprodukte
  • Geräte-Hilfsverarbeitung
  • Hintergrundsynchronisierung

3.2. DPC / ISR und Treiber

Dieser Punkt ist ziemlich wichtig. Selbst wenn die Priorität auf App-Seite sauber eingestellt ist, kann während eines langen DPC (Deferred Procedure Call) oder ISR (Interrupt Service Routine) kein User-Mode-Thread ausgeführt werden.

Häufige Ursachen sind Geräte und Treiber aus diesem Bereich.

  • USB
  • WLAN / Bluetooth
  • Storage
  • Audio
  • GPU
  • ACPI / Energieverwaltung

Auch wenn der App-Code selbst nichts falsch macht, kann er durch Treiber- oder Hardware-Gegebenheiten ausgebremst werden. Wer hier denkt „wenn ich die Priorität der App nur weiter erhöhe, gewinne ich schon“, zieht sich damit meist eine blutige Nase zu.

3.3. Page Faults und Speicher

Tritt im Hot Path ein Page Fault auf (eine benötigte Seite ist nicht im Speicher und muss erst geholt werden), schnellt die Latenz sprunghaft nach oben.

Besonders vermeiden sollten Sie diese Muster.

  • Page-Commit beim ersten Zugriff
  • Lazy Loading
  • Page-in von Memory-Mapped-Dateien
  • Mehr dynamische Allokation als nötig
  • Große Objekte oder ein fragmentierter Heap

Im Kern der periodischen Verarbeitung ist es genau richtig, den benötigten Speicher vorab zu reservieren und ihn beim Start einmal anzufassen.

3.4. Timer-Auflösung und Energieverwaltung

„Ich will alle 1 ms laufen, also Sleep(1)“ funktioniert in den meisten Fällen nicht. Die Wartepräzision von Windows wird von Timer-Auflösung, Scheduling und Energiezustand beeinflusst.

Zudem darf man nicht übersehen, dass eine Einstellung, die die Timer-Auflösung erhöht, zwar die Wartepräzision etwas verbessert, aber Nebenwirkungen auf den Stromverbrauch und das Verhalten des Gesamtsystems hat.

3.5. Core-Wechsel und Wärme

Wandert ein Thread zwischen Cores, muss sich der Cache neu aufwärmen. Das handhabt das Betriebssystem selbst oft gut, aber unter hoher Last wird es zu einer Ursache für Schwankungen.

Bei langem Betrieb ist außerdem die Wärme nicht zu vernachlässigen. Setzt Thermal Throttling ein, kann eine bis dahin stabile Periode zusammenbrechen.

4. Praktische Checkliste, um Verzögerungen auf gewöhnlichem Windows zu reduzieren

Ab hier beginnt der praktische Teil. Für die im vorigen Abschnitt gesehenen Ursachen fassen wir in Checklistenform zusammen, was auf gewöhnlichem Windows zu prüfen, was zu vermeiden und was zuerst zu entscheiden ist.

4.1. Periodische Schleife und Wartemethode

Zunächst das klassische Anti-Pattern.

while (running)
{
    Sleep(1);
    Step();
}

Das ist keine „1-ms-Periode“, sondern eine Schleife, die ungefähr 1 ms oder länger wartet und dann noch die Ausführungszeit von Step() obendrauf legt. Und der Warte-Overshoot summiert sich dabei unmittelbar.

Absolute Deadline-BasisRelative ZeitbasisWaitUntil(next - margin)next += periodBei Bedarf kurzer SpinFastStep()Step()Sleep(1)Wartefehler und Ausführungszeit summieren sich Stück für StückSammelt kaum Drift an

Checkliste

  • Die periodische Schleife basiert nicht auf Sleep(1)
  • Die Periode läuft über die absolute Deadline mittels next += period
  • Beim Warten wird ein Geräte-Ereignis oder ein waitable timer (wartbarer Timer) bevorzugt
  • Nur die letzte Feinjustierung ist auf einen ganz kurzen Busy-Spin (Leerlauf-Warteschleife) beschränkt
  • timeBeginPeriod wird nur solange verwendet, wie nötig, und danach zurückgesetzt
  • Das Verhalten wurde auch im minimierten / ausgeblendeten / unsichtbaren Zustand geprüft

Eine periodische Schleife ist stabiler, wenn sie über die absolute Deadline statt über relative Zeit läuft.

int64_t next = QpcNow() + periodTicks;

while (running)
{
    WaitUntil(next - wakeMarginTicks);

    while (QpcNow() < next)
    {
        CpuRelax(); // Nur am Ende kurz spinnen
    }

    int64_t started = QpcNow();
    FastStep();
    int64_t finished = QpcNow();

    RecordTiming(next, started, finished);

    next += periodTicks;

    while (finished > next)
    {
        ++missedDeadlines;
        next += periodTicks;
    }
}

4.2. fast path / slow path und Queue fester Länge

Die Grundstruktur besteht darin, im fast path nur „deadline-sensitive Arbeit“ zu platzieren und alles andere in den slow path auszulagern.

Gerät / Erfassungs-Ereignisfast path: Erfassung, Steuerung, minimales KopierenQueue fester Längeslow path: Speicherung, Versand, UI, Aggregationlateness / miss / Queue-Tiefe aufzeichnen

Im fast path beschränken Sie sich auf etwa diese Aufgaben.

  • Datenerfassung
  • Berechnung des Steuerwerts
  • Minimal notwendiges Kopieren
  • Zeitstempel
  • Einreihen in die Queue
  • Aufzeichnen von Miss / Overrun

Alles andere fällt in den slow path.

Checkliste

  • Im Hot Path werden keine Dateien geschrieben, keine Netzwerkversendungen und keine DB-Schreibvorgänge vorgenommen
  • Im Hot Path gibt es kein schweres Logging, kein Flush und keinen synchronen RPC
  • fast path und slow path sind klar nach Thread oder Zuständigkeit getrennt
  • Die Queue hat eine feste Länge
  • Die Vorgehensweise bei einem Queue-Überlauf ist vorab festgelegt
  • Miss-Anzahl, Drop-Anzahl und Queue-Tiefe werden beobachtet
  • UI-Aktualisierung und Log-Aggregation sind auf eine niedrigere Frequenz ausgelagert

Ist die Queue voll, ist es sicherer, die Vorgehensweise nicht offenzulassen.

Der aktuellste Wert zähltJeder Eintrag zähltFür LoggingQueue ist vollWas wird geschützt?Alte Elemente verwerfen, den aktuellsten behaltenAlarm / Stopp / Steuerung stromaufwärtsAlte Elemente verwerfen, nur die Drop-Anzahl aufzeichnen

4.3. Priorität / MMCSS / Background Mode

Die Grundregel bei der Priorität lautet: nicht alles anheben. Auf gewöhnlichem Windows funktioniert es besser, „nur die wichtigen Threads anzuheben und die Hintergrundarbeit konsequent abzusenken“. Background Mode ist ein Mechanismus, der nicht nur die CPU, sondern auch Ressourcen wie I/O in Richtung niedrigerer Priorität behandelt.

Arbeit aufteilenDeadline-sensitive ThreadsSpeicherung / Versand / Kompression / AggregationUIBei Bedarf höhere Priorität oder MMCSSBackground Mode / niedrigere PrioritätNormale PrioritätNicht von Anfang an REALTIME_PRIORITY_CLASS verwenden

Checkliste

  • Nicht alle Threads sind auf hohe Priorität gesetzt
  • Nur die wirklich zeitkritischen Threads sind angehoben
  • Hintergrundarbeit wie Speicherung, Versand, Kompression und Synchronisierung ist auf Background Mode abgesenkt
  • Bei kontinuierlicher Pufferverarbeitung wie Audio, Video, Capture oder Wiedergabe wird MMCSS in Betracht gezogen
  • Es wird zuerst pro Thread gedacht, nicht für den gesamten Prozess
  • REALTIME_PRIORITY_CLASS wird nicht verwendet, bevor die Notwendigkeit eindeutig feststeht

MMCSS (Multimedia Class Scheduler Service) ist besonders wirksam bei Verarbeitung wie Audio/Video, bei der „der Puffer innerhalb einer festen Zeit gefüllt werden soll“. Das entspricht eher dem Windows-Design, als einfach dauerhaft einen hochprioren Thread laufen zu lassen.

So sieht der Code ungefähr aus.

DWORD taskIndex = 0;
HANDLE avrt = AvSetMmThreadCharacteristicsW(L"Pro Audio", &taskIndex);
if (!avrt)
{
    throw std::runtime_error("AvSetMmThreadCharacteristicsW failed");
}

// Die zeitkritische Schleife ausführen

if (!AvRevertMmThreadCharacteristics(avrt))
{
    throw std::runtime_error("AvRevertMmThreadCharacteristics failed");
}

4.4. Speicher / GC / Erstkosten

Wenn Sie im Hot Path bei jedem Durchlauf new / malloc / List<T>.Add / String-Verkettung / LINQ verwenden, treten irgendwann die Kosten von Freigabe und Umlagerung zutage. GC (Garbage Collection) selbst ist nicht der Übeltäter, aber wenn Sie allokationsintensiven Code schreiben, zeigt sich dessen Auswirkung als Jitter.

StartBenötigte Puffer reservierenEinmal anfassen, um die Seiten aufzuwärmenJIT / DLL-Laden / ersten I/O erledigenDanach die eigentliche Messung / den eigentlichen Betrieb

Checkliste

  • Im Hot Path werden nicht bei jedem Durchlauf Speicher reserviert / freigegeben
  • Benötigte Puffer sind beim Start vorab reserviert
  • Die Seiten wurden beim Start einmal angefasst, um sie aufzuwärmen
  • Erstes JIT, erstes DLL-Laden und erster I/O werden nicht in die eigentliche Messung gemischt
  • In der Schleife wachsen keine riesigen Strukturen oder Logs mit variabler Länge
  • VirtualLock wird, falls überhaupt verwendet, nur auf einen ganz kleinen kritischen Bereich beschränkt

.NET-seitige Prüfpunkte

  • Für die Zeitmessung werden Stopwatch / Stopwatch.GetTimestamp() verwendet
  • Im Hot Path gibt es kein LINQ, keine String-Verkettung, kein ToString() und keine Erzeugung riesiger Logs
  • async/await wird nicht in den Hot Path hineingetragen
  • Vor und nach dem Warm-up wird getrennt bewertet

4.5. Energieeinstellungen / EcoQoS / Timer-Auflösung

Dieser Punkt ist unscheinbar, wirkt aber. Selbst wenn der Code optimiert ist, wird das Ergebnis nicht stabil, wenn die übergeordnete Energiesteuerung stark hineinwirkt.

Energieverwaltung auf gewöhnlichem WindowsMit AC-Stromversorgung ausführenEnergiemodus: in Richtung Beste LeistungBei Bedarf ein dediziertes Energieprofil für den ProduktivbetriebZeitkritische Prozesse von EcoQoS fernhaltenUmgang mit Timer-Auflösungsanforderungen prüfen

Checkliste

  • Die Produktivbewertung erfolgt zuerst mit AC-Stromversorgung
  • [Einstellungen] > [System] > [Netzbetrieb & Akku] > [Energiemodus] ist in Richtung Beste Leistung gesetzt
  • Der Batteriesparmodus bzw. ein energiesparpriorisierter Modus ist während des Betriebs nicht aktiv
  • Herstellerspezifische Utilities mit Silent-/Eco-/Batterie-Priorität-Modus wurden geprüft
  • Zeitkritische Prozesse sind nicht versehentlich auf EcoQoS (energiesparlastiges QoS) gesetzt
  • IGNORE_TIMER_RESOLUTION ist auf der zeitkritischen Prozessseite nicht aktiv
  • Es wurde geprüft, ob die Wirkung der Timer-Auflösungsanforderung sich bei Minimierung / Ausblendung ändert
  • Die Energieeinstellungen für den Alltagsgebrauch und für Produktivbetrieb / Messung / Demo sind getrennt

timeBeginPeriod ist nützlich, wenn es organisiert eingesetzt wird, aber kein Allheilmittel.

  • Unmittelbar vor Bedarf aufrufen
  • Nach Abschluss mit timeEndPeriod zurücksetzen
  • Ab Windows 10 Version 2004 ist das Verhalten nicht mehr vollständig global wie früher
  • Unter Windows 11 kann bei einem Prozess mit Fenster, das vollständig verdeckt / minimiert / unsichtbar / stumm ist, die hohe Auflösung nicht garantiert sein
  • Eine höhere Auflösung erhöht nicht die Präzision von QPC

Ist ein Einfluss von Strom oder QoS zu vermuten, prüfen Sie mit SetProcessInformation den Zustand des Power Throttling.

PROCESS_POWER_THROTTLING_STATE state{};
state.Version = PROCESS_POWER_THROTTLING_CURRENT_VERSION;
state.ControlMask =
    PROCESS_POWER_THROTTLING_EXECUTION_SPEED |
    PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION;
state.StateMask = 0; // HighQoS (leistungsorientiert) + Timer-Auflösungsanforderung respektieren

if (!SetProcessInformation(
        GetCurrentProcess(),
        ProcessPowerThrottling,
        &state,
        sizeof(state)))
{
    throw std::runtime_error("SetProcessInformation failed");
}

ControlMask legt fest, „welche Mechanismen selbst gesteuert werden“, StateMask, „ob dieser Mechanismus ein- oder ausgeschaltet wird“. Im obigen Beispiel werden zwei Mechanismen zur Steuerung ausgewählt und beide auf „aus“ gesetzt. Das ist also die Erklärung, nicht auf EcoQoS herabzustufen (Richtung HighQoS) und die Timer-Auflösungsanforderung nicht ignorieren zu lassen. Setzt man ControlMask dagegen auf 0, werden beide wieder dem Betriebssystem überlassen (Standardverhalten).

Beim Aufruf aus C#

Soll dasselbe aus C# geschehen, sieht die P/Invoke-Deklaration so aus.

// C# / .NET 8
using System.Runtime.InteropServices;

internal static class PowerQos
{
    [StructLayout(LayoutKind.Sequential)]
    private struct PROCESS_POWER_THROTTLING_STATE
    {
        public uint Version;
        public uint ControlMask;
        public uint StateMask;
    }

    private const uint PROCESS_POWER_THROTTLING_CURRENT_VERSION = 1;
    private const uint PROCESS_POWER_THROTTLING_EXECUTION_SPEED = 0x1;
    private const uint PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION = 0x4;

    // Der 5. Wert von PROCESS_INFORMATION_CLASS (nullbasiert: 4) ist ProcessPowerThrottling
    private const int ProcessPowerThrottling = 4;

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool SetProcessInformation(
        IntPtr hProcess,
        int processInformationClass,
        ref PROCESS_POWER_THROTTLING_STATE processInformation,
        uint processInformationSize);

    [DllImport("kernel32.dll")]
    private static extern IntPtr GetCurrentProcess();

    /// <summary>Hebt sowohl die Einstufung Richtung Energiesparen als auch das Ignorieren der Timer-Auflösungsanforderung auf.</summary>
    public static void OptOutOfPowerThrottling()
    {
        var state = new PROCESS_POWER_THROTTLING_STATE
        {
            Version = PROCESS_POWER_THROTTLING_CURRENT_VERSION,
            ControlMask =
                PROCESS_POWER_THROTTLING_EXECUTION_SPEED |
                PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION,
            StateMask = 0,
        };

        if (!SetProcessInformation(
                GetCurrentProcess(),
                ProcessPowerThrottling,
                ref state,
                (uint)Marshal.SizeOf<PROCESS_POWER_THROTTLING_STATE>()))
        {
            throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
        }
    }
}

Der Aufruf erfolgt, indem Sie vor Beginn der zeitkritischen Schleife einmal PowerQos.OptOutOfPowerThrottling(); ausführen. Das Prozess-Handle benötigt die Zugriffsrechte PROCESS_SET_INFORMATION, aber mit dem von GetCurrentProcess() zurückgegebenen Pseudo-Handle des eigenen Prozesses gibt es kein Problem.

4.6. CPU-Platzierung / Core-Wechsel / Wärme

Bei der CPU-Platzierung funktioniert es oft besser, nicht sofort auf feste Bindung an bestimmte Cores (Hard Affinity / CPU Pinning) zu setzen, sondern mit einer Angabe zu beginnen, die näher an Soft Affinity liegt: „bitte möglichst auf dieser Core-Gruppe laufen“.

JaNeinZuerst messenSetThreadIdealProcessor / CPU SetsAusreichend verbessert?Dort stehen bleibenZuletzt SetThreadAffinityMask erwägenGleichzeitig Temperatur / Takt / Langzeitbetrieb prüfen

Checkliste

  • Die CPU-Platzierung wird erst nach der Messung angepasst
  • Es wird nicht sofort auf bestimmte Cores fixiert
  • Zuerst werden SetThreadIdealProcessor oder CPU Sets ausprobiert
  • SetThreadAffinityMask wird als letztes Mittel behandelt
  • Temperatur, Takt und Thermal Throttling werden über lange Laufzeit geprüft
  • Der Silent- oder Low-Noise-Modus von Notebooks wird geprüft

Als Reihenfolge ist dieser Ablauf sicher.

  1. Zuerst messen
  2. Bei Bedarf ideal processor / CPU Sets
  3. Ist weitere Verbesserung nötig, feste Core-Bindung

Eine feste Core-Bindung sieht nach einer wirksamen Maßnahme aus, verringert aber die Ausweichmöglichkeiten des Betriebssystems – wird sie leichtfertig eingesetzt, kann das die Flexibilität stattdessen verringern.

4.7. Treiber / DPC / ISR / externe Störungen isolieren

Wenn „nur das Maximum gelegentlich explodiert“ oder „der Mittelwert gut ist, aber p99.9 schlecht“ ist, lohnt es sich, auch externe Störungen außerhalb des eigenen App-Codes in Verdacht zu nehmen.

JaNeinJaNeinJaNeinJaNeinlate / miss / max Spike ist aufgetretenIst die eigene Verarbeitungszeit auch lang?Hot Path verkürzen / Allokationen reduzieren / I/O entfernenGibt es DPC / ISR Spitzen?USB / WLAN / Bluetooth / GPU / Audio / Storage / ACPI / Treiberupdates prüfenGibt es Page Faults / GC / Erstkosten?Vorab reservieren / Warm-up / Heap-Last reduzierenGibt es Einfluss von Batterie / Energiesparen / Wärme?AC-Stromversorgung / Energieeinstellungen / Kühlung / LangzeittestMit ETW / WPA / LatencyMon tiefer graben

Checkliste

  • Treiber rund um WLAN / Bluetooth / USB / Storage / GPU / Audio sind geprüft
  • Es wurde mit gestoppter unnötiger Cloud-Synchronisierung, Indizierung und automatischen Updates verglichen
  • Es wurde auch getestet, ob es bei Minimierung oder abgeschaltetem Bildschirm zu Ausfällen kommt
  • Die Tendenz von DPC / ISR wurde mit LatencyMon oder ETW betrachtet
  • Es wurde getrennt betrachtet, ob „die eigene Verarbeitung schwer ist“ oder „man von außen ausgebremst wird“

5. Messung und Bewertung

5.1. Was aufgezeichnet werden sollte

Mindestens diese Werte sollten Sie erfassen.

  • Geplanter Periodenzeitpunkt
  • Tatsächlicher Startzeitpunkt
  • Tatsächlicher Endzeitpunkt
  • Lateness (wie stark der Start gegenüber dem geplanten Beginn verzögert war)
  • Ausführungszeit
  • Anzahl der Missed Deadlines
  • Anzahl aufeinanderfolgender Missed Deadlines
  • Queue-Tiefe
  • Drop-Anzahl
  • CPU-Auslastung
  • Verteilung nach Core
  • DPC / ISR Spitzen
  • Page Faults
  • Temperatur- / Taktschwankungen

Betrachtet man nur den Mittelwert, lässt sich der Kern der Sache schwer erfassen. Was im Produktivbetrieb Probleme macht, sind die gelegentlichen großen Latenzspitzen.

5.2. Wie p99 / p99.9 / max zu lesen sind

Kennzahlen wie p99 dienen dazu, die langsame Seite der Verteilung zu betrachten. Mit dem Mittelwert allein bleiben gelegentliche große Verzögerungen verborgen.

Kennzahl Bedeutung Vorstellung bei 10.000 Messungen
Mittelwert Der geglättete Gesamtwert Spitzen gehen leicht unter
p50 Der mittlere Wert Nahe am alltäglichen Gefühl
p95 Die Schwelle, ab der die langsamsten 5 % sichtbar werden Die Grenze nach Ausschluss der langsamsten 500
p99 Die Schwelle, ab der die langsamsten 1 % sichtbar werden Die Grenze nach Ausschluss der langsamsten 100
p99.9 Die Schwelle, ab der die langsamsten 0,1 % sichtbar werden Die Grenze nach Ausschluss der langsamsten 10
max Der schlechteste Wert Der eine langsamste Durchlauf

Nehmen wir zum Beispiel folgende Werte an (dies ist ein Beispiel, um das Lesen der Kennzahlen zu erklären, keine tatsächliche Messung auf einer bestimmten Hardware).

  • Mittelwert: 0,8 ms
  • p99: 1,2 ms
  • p99.9: 3,5 ms
  • max: 28 ms

Das ist ein Zustand, in dem die Verarbeitung normalerweise schnell ist, aber gelegentlich große Spitzen auftreten. Auf gewöhnlichem Windows zeigt sich das eigentliche Problem meist genau in dieser Schleppe von p99 bis max.

Dieser Artikel zeigt die Wirkung der empfohlenen Konfiguration übrigens nicht in Zahlen. Latenz und Jitter ändern sich leicht je nach CPU, Treibern, residenter Software, Energieeinstellungen und Art der Belastung, daher sind Zahlen aus einer fremden Umgebung kein Beleg für die eigene Umgebung. Stattdessen finden Sie hier eine Anleitung, um in Ihrer eigenen Umgebung eine Tabelle derselben Form zu erstellen.

Minimales Vorgehen, um in der eigenen Umgebung p99 zu ermitteln

  1. Im Hot Path wird nur aufgezeichnet. Mit Stopwatch.GetTimestamp() (unter C++ QueryPerformanceCounter) werden Lateness und Ausführungszeit erfasst und in ein vorab reserviertes Array geschrieben. Mittelwert oder Sortierung dürfen hier nicht berechnet werden
  2. Die Auswertung erfolgt erst, nachdem die Messung gestoppt wurde. Sortieren Sie und entnehmen Sie die Werte an den Perzentil-Positionen
  3. Wiederholen Sie dasselbe Vorgehen unter verschiedenen Bedingungen: vor/nach dem Warm-up, AC/Batterie, UI im Vordergrund/minimiert, mit/ohne Last durch andere Prozesse (5.4)
  4. Nach jeder einzelnen Änderung nehmen Sie unter denselben Bedingungen erneut Messwerte auf und vergleichen
// C# / .NET 8. Die Auswertung erfolgt erst, nachdem die Messung gestoppt wurde
using System.Diagnostics;

// Im Hot Path wird nur in das Array geschrieben (keine Allokation)
long[] latenessTicks = new long[100_000];
int count = 0;

// Beispiel: innerhalb der periodischen Schleife
// latenessTicks[count++] = Stopwatch.GetTimestamp() - scheduledTimestamp;

static double PercentileMs(long[] ticks, int count, double percentile)
{
    long[] sorted = ticks.AsSpan(0, count).ToArray();
    Array.Sort(sorted);

    int index = (int)Math.Ceiling(percentile / 100.0 * count) - 1;
    index = Math.Clamp(index, 0, count - 1);

    return sorted[index] * 1000.0 / Stopwatch.Frequency;
}

// Verwendung
// Console.WriteLine($"p50={PercentileMs(latenessTicks, count, 50):F3}ms");
// Console.WriteLine($"p99={PercentileMs(latenessTicks, count, 99):F3}ms");
// Console.WriteLine($"p99.9={PercentileMs(latenessTicks, count, 99.9):F3}ms");
// Console.WriteLine($"max={PercentileMs(latenessTicks, count, 100):F3}ms");

Stopwatch.Frequency ist die Anzahl der Zählschritte pro Sekunde; teilt man dadurch und multipliziert mit 1000, erhält man Millisekunden. Bei zu wenigen Stichproben hat p99.9 keine Aussagekraft. Wenn Sie über p99.9 sprechen wollen, sammeln Sie mindestens 10.000 Stichproben (idealerweise 100.000).

5.3. Womit gemessen wird

Das Werkzeug-Set ist weitgehend festgelegt.

  • In-App-Messung Zunächst selbst period / lateness / execution time / queue depth / drop erfassen
  • ETW / WPR / WPA CPU, Context Switches, DPC / ISR, Page Faults untersuchen
  • LatencyMon Eine Vermutung zu treiberbedingten Schwankungen eingrenzen
  • Temperatur- / Taktüberwachung Wärmeeinflüsse betrachten
In-App-Messungp50 / p95 / p99 / p99.9 / maxmiss / drop / Queue-TiefeETW / WPR / WPAContext Switch / DPC / ISR / Page FaultTemperatur- / TaktüberwachungPriorität der Verbesserungen festlegen

Bis zu WPA vorzudringen erfordert etwas Mühe, ist aber ziemlich wirksam, um zu unterscheiden, ob DPC / ISR die Ursache sind oder die eigene Verarbeitung einfach schwer ist.

Bezugsquelle und minimale Nutzung

Tool Bezugsquelle Minimales Vorgehen
WPR / WPA (Windows Performance Toolkit) Wird bei der Installation des Windows ADK (Windows Assessment and Deployment Kit) installiert, wenn Sie „Windows Performance Toolkit“ auswählen. Standardort: C:\Program Files (x86)\Windows Kits\10\Windows Performance Toolkit Öffnen Sie die Eingabeaufforderung als Administrator, (1) starten Sie die Aufzeichnung mit wpr -start CPU, (2) lassen Sie den betroffenen Prozess einige Dutzend Sekunden laufen, (3) speichern Sie mit wpr -stop trace.etl "Untersuchung periodischer Verzögerungen". Öffnen Sie anschließend trace.etl mit WPA. Die verfügbaren Profilnamen erhalten Sie mit wpr -profiles
LatencyMon Download von der Website von Resplendence Software. Die Home Edition für Privatanwender ist kostenlos Starten Sie das Tool, beginnen Sie die Messung und lassen Sie den betroffenen Prozess einige Minuten laufen. Erfasst werden die maximale Verzögerung des Kernel-Timers sowie die ISR-/DPC-Ausführungszeit und Hard Page Faults pro Treiber – notieren Sie sich die Treiber mit auffällig hoher Ausführungszeit

In WPA schauen Sie zuerst bei den CPU-bezogenen Diagrammen auf die Ausführungszeit von DPC / ISR und Context Switches. Dort erscheint, „welcher Treiber in der Zeit, in der der eigene Thread nicht laufen konnte, die CPU belegt hatte“, sodass Sie das mit den in 5.1 erfassten Verzögerungszeitpunkten abgleichen können.

Dieser Artikel enthält übrigens keine Bildschirmfotos. Da sich das Erscheinungsbild je nach Version leicht ändert, führen Sie die obigen Schritte selbst aus und prüfen Sie es am tatsächlichen Bildschirm.

5.4. Die Vorgehensweise beim Testen

Ein ruhiges Testlabor allein genügt beim Testen nicht. Mindestens diese Bedingungen sollten getrennt betrachtet werden.

  • Direkt nach dem Start, vor dem Warm-up
  • Nach dem Warm-up
  • Langer Dauerbetrieb
  • UI im Vordergrund
  • UI minimiert / nahezu ausgeblendet
  • AC-Stromversorgung
  • Batteriebetrieb
  • Zustand mit Last auf Netzwerk oder Festplatte

Bewertet man nur im Testlabor, übersieht man leicht Probleme, die im echten Betrieb auftreten. Das Verhalten von gewöhnlichem Windows wird stark von der „Art der Nutzung“ beeinflusst, daher ist es wichtig, unter Bedingungen zu prüfen, die den tatsächlichen Nutzungsbedingungen nahekommen.

6. Grobe Entscheidungshilfe

Die Kurzübersicht nach Periodenbereich wurde nach 1.1 vorgezogen, damit Sie beim Lesen dorthin zurückspringen können. Hier ergänzen wir zwei Entscheidungen, die sich aus dieser Tabelle allein nicht ableiten lassen.

Wo Sie entscheiden, dass „mit gewöhnlichem Windows nicht mehr geht“

Wenn Sie unter 1 ms über lange Zeit und bei hoher Last einhalten müssen, ist es oft schneller, nur den zeitkritischen Teil auszulagern, statt weiter zu tunen. Kandidaten für die Auslagerung sind geräteseitige Firmware, ein dedizierter Controller, ein FPGA oder ein RTOS. Als Entscheidungsgrundlage dienen nicht subjektive Eindrücke, sondern die Zahlen aus Kapitel 5.

  • Der Hot Path lässt sich nicht weiter verkürzen, und p99.9 sowie max überschreiten weiterhin die Anforderung
  • Die Ursache liegt in externen Störungen (DPC / ISR, Treiber, andere Prozesse) und ist mit Maßnahmen auf App-Seite nicht erreichbar (durch die Eingrenzung in 4.7 bestätigt)
  • Die Anforderung lautet nicht mehr „bricht nicht zusammen, wenn gelegentlich verfehlt“, sondern „darf kein einziges Mal verfehlt werden“

Wenn Sie alles in einem Prozess unterbringen wollen

Packt man GUI, Logging, Kommunikation und DB in dieselbe Schleife desselben Prozesses, bricht das, was der nachgelagerte Teil braucht, die Deadline des vorgelagerten Teils. Denn das Warten auf einen Datei-Flush, eine DB-Neuverbindung oder ein UI-Neuzeichnen kann sich jeweils um mehrere Dutzend Millisekunden verlängern. Eine Option ist es, die Trennung von fast path / slow path (4.2) nicht nur auf Thread-, sondern auf Prozessebene auszuweiten. Trennt man die Prozesse, läuft die Periode des vorgelagerten Teils weiter, auch wenn der nachgelagerte Teil hängen bleibt.

7. Zusammenfassung

Es gibt zwei Grundannahmen, die Sie im Kopf behalten sollten.

  • Was auf gewöhnlichem Windows angestrebt wird, ist keine Hard-Real-Time-Garantie, sondern eine Soft-Real-Time-Konfiguration: Latenz und Jitter klein halten und nicht zusammenbrechen, wenn eine Terminverletzung auftritt
  • Am wirkungsvollsten ist das Aufräumen des Hot Path, mehr als die Anpassung der Priorität

Auf der Implementierungsseite zahlt sich das hier aus.

  • fast path und slow path trennen
  • Queue fester Länge verwenden und die Vorgehensweise bei Überlauf vorab festlegen
  • Mit QPC messen, mit Event / waitable timer (wartbarem Timer) warten
  • Im Hot Path Allokation, blockierende I/O und schwere Locks vermeiden

Auf der Betriebsseite zahlt sich das hier aus.

  • Mit AC-Stromversorgung betreiben
  • Ein separates Energieprofil für den Produktivbetrieb pflegen
  • Unnötige Hintergrundlast reduzieren
  • Mit p99 / p99.9 / max und der Anzahl der Misses bewerten

Soft Real-Time auf gewöhnlichem Windows wird nicht allein durch die Prioritätseinstellung bestimmt – wenn Sie Entwurf, Implementierung, Energieeinstellungen, Messung und Betrieb getrennt durcharbeiten, lässt sich daraus ein durchaus stabiles System bauen.

8. Quellen

Aktuelle Artikel mit denselben Schlagwörtern führen zu verwandten Themen weiter.

Diese Seiten ordnen den Artikel in einen größeren Leistungs- und Entscheidungskontext ein.

Dieser Artikel ist direkt mit den folgenden Leistungen verbunden.

Häufige Fragen

Fragen, die in Beratungen zu diesem Artikelthema häufig gestellt werden.

Kann Windows Echtzeitverarbeitung leisten?
Eine Hard-Real-Time-Garantie (null Terminverletzungen) ist nicht möglich, aber wenn Entwurf, Implementierung, Messung und Betrieb sauber durchgearbeitet werden, lässt sich als Soft Real-Time ein durchaus praxistauglicher Zustand erreichen. Periodische Verarbeitung im Bereich von wenigen bis einigen Dutzend Millisekunden, pufferbasiertes Audio/Video, Sensorerfassung und Regelschleifen sind auf gewöhnlichem Windows 10/11 realistisch. Werden dagegen null Terminverletzungen oder eine über lange Zeit stabile Einhaltung von wenigen hundert Mikrosekunden oder weniger benötigt, sollte man in Richtung RTOS, dedizierter Controller, FPGA oder geräteseitige Verarbeitung ausweichen.
Warum sollte man in einer periodischen Verarbeitung kein Sleep(1) verwenden?
Sleep(1) erzeugt keine „1-ms-Periode“, sondern ein Verhalten, das „ungefähr 1 ms oder mehr wartet und dann die Ausführungszeit noch obendrauf legt“ – und der Warte-Overshoot summiert sich unmittelbar. Stabiler ist es, die periodische Schleife über die absolute Deadline next += period laufen zu lassen, beim Warten ein Geräte-Ereignis oder einen hochauflösenden waitable timer zu bevorzugen und nur die letzte Feinjustierung auf einen ganz kurzen Busy-Spin zu beschränken. timeBeginPeriod wird nur solange verwendet, wie es nötig ist, und danach wieder zurückgesetzt.
Was hilft am meisten, um Latenz und Jitter zu reduzieren?
Mehr als das Erhöhen der Priorität hilft es, den Hot Path kurz, fest in der Länge und nicht-blockierend zu halten. Trennen Sie fast path (Erfassung/Steuerung) und slow path (Speicherung/Kommunikation/UI) und verbinden Sie beide über eine Queue fester Länge; im Hot Path vermeiden Sie Dateischreibvorgänge, Netzwerkversand, schweres Logging und Speicherzuweisungen bei jedem Durchlauf. Im laufenden Betrieb zahlen sich AC-Stromversorgung, ein überarbeiteter Energiemodus, die Kontrolle über EcoQoS und das Aufräumen der Hintergrundlast aus.
Mit welchen Kennzahlen sollte die Stabilität periodischer Verarbeitung bewertet werden?
Nicht nur mit dem Mittelwert, sondern mit p99, p99.9, max und der Anzahl der Deadline Misses. Liegt der Mittelwert etwa bei 0,8 ms, das Maximum aber bei 28 ms, ist die Verarbeitung normalerweise schnell, hat aber gelegentlich große Ausreißer – und auf gewöhnlichem Windows liegt das eigentliche Problem meist genau in dieser Schleppe von p99 bis max. Ergänzend sollten DPC-/ISR-Spitzen, Page Faults, Queue-Tiefe sowie Temperatur- und Taktschwankungen erfasst und Bedingungen wie vor/nach dem Warm-up, Langzeitbetrieb, minimierter Zustand und Batteriebetrieb getrennt bewertet werden.

Autorenprofil

Profilseite des Artikelautors.

Go Komura

Geschäftsführer von KomuraSoft LLC

Spezialisiert auf Windows-Softwareentwicklung, technische Beratung und Fehleranalyse, insbesondere bei bestehenden Systemen und schwer reproduzierbaren Störungen.

Zurück zum Blog