Energie- en thermische functies beheren
Wanneer de HoloLens 2 wordt uitgevoerd in warme omgevingen of met zware prestatievereisten (CPU-/GPU-gebruik, randapparatuurgebruik, enzovoort), kan het zo heet worden dat het automatisch acties onderneemt om te voorkomen dat ze oververhit raken. Deze acties omvatten zaken als:
- Laadprestaties aanpassen
- Feedback van gebruikers geven
- Toepassingen sluiten
... en in het slechtste geval:
- De HoloLens 2 afsluiten
Als uw toepassing hoge randapparatuurprestaties vereist, kunt u overwegen om de PowerThermalNotification Software Development Kit (SDK) te gebruiken om u te abonneren op meldingsgebeurtenissen en uw eigen aangepaste acties te implementeren. Als u dit doet, kan het apparaat langer werken in situaties wanneer anders een toepassing door het systeem kan worden beëindigd.
Notitie
Ondersteuning voor de Microsoft.MixedReality.PowerThermalNotification SDK is opgenomen in de 22H1-release.
In dit artikel worden de PowerThermalNotification SDK en het basisgebruik ervan beschreven om u op weg te helpen.
Waar kan ik de SDK downloaden?
De PowerThermalNotification SDK kan worden gedownload via het Mixed Reality Feature Tool.
PowerThermalNotification SDK ondersteunt taalprojecties voor C# en C++, zodat ontwikkelaars toepassingen kunnen ontwikkelen voor Win32- of UWP-platforms.
Conceptueel overzicht
Het vermogen dat door de HoloLens 2 wordt verbruikt, wordt in warmte afgenomen. Een traditioneel pc-apparaat zou een ventilator hebben om dit aan te pakken, maar een draagbaar apparaat moet licht van gewicht zijn. Hierdoor is de koeloplossing complexer. HoloLens 2 heeft ingebouwde veiligheidsfuncties voor hardware en software om ervoor te zorgen dat de headset niet te heet wordt voor de gebruiker, maar deze functies moeten ook worden afgewogen met de gebruikerservaring. Als we bijvoorbeeld weten welk deel van de HoloLens 2 opwarmt, kunnen we ervoor kiezen om de randapparatuur te beperken die verantwoordelijk is voor deze warmte. Als laatste redmiddel kunnen we een toepassing sluiten waarvan wordt gedacht dat deze verantwoordelijk is voor de stroom die tot deze hitte heeft geleid.
HoloLens 2 verwerkt warmteproblemen met behulp van temperatuursensoren. Een thermisch framework verbindt groepen sensoren met verschillende randapparatuur op het apparaat. De sensoren zijn gegroepeerd omdat het onmogelijk kan zijn om te bepalen welk randapparaat in een fysieke ruimte verantwoordelijk is voor de stroomopname die de HoloLens 2 opwarmt.
De PowerThermalNotification SDK maakt de API's beschikbaar die nodig zijn om deze groepen sensoren te bewaken. SDK-gebeurtenissen worden geactiveerd wanneer een randapparaat dat door de toepassing wordt gebruikt, signalen vertoont dat een beperking mogelijk is vereist. De toepassing kan vervolgens de klantervaring aanpassen om de thermische impact te verminderen. Het verminderen van de impact betekent minder risico op systeemacties, zoals het afsluiten van toepassingen of apparaten.
Een eenvoudig voorbeeld is een toepassing die gebruikmaakt van de CPU om een grote hoeveelheid videogegevens te verwerken. De toepassing kan zich abonneren op een prestatiemelding voor het CPU-onderdeel. Wanneer de toepassing een melding ontvangt, kan dit de CPU-werkbelasting verminderen. Als er een andere gebeurtenis wordt ontvangen die aangeeft dat er geen verdere beperking nodig is, kan de CPU-workload worden hersteld.
Platformreactie
De volgende tabel is een uitsplitsing van systeemacties per randapparaat. Acties die hieronder worden beschreven, kunnen worden onderdrukt met behulp van de SDK. Zie Standaardsysteembeperkingen onderdrukken
Perifere | MinimumUserImpact | MediumUserImpact | MaximumUserImpact | Laatste redmiddel | Software afsluiten | Failsafe |
---|---|---|---|---|---|---|
GPU | VSYNC-interval van MRC-kwaliteit aanpassen beperken |
|||||
Weergave | Diepte-FPS-reductie | |||||
Elk randapparaat | Weergavewaarschuwing Toepassingsstop MRC Capture sluiten |
Besturingssysteem afsluiten | Hardware afsluiten |
Notitie
Acties in de kolommen Last Resort, Software Shutdown en Failsafe kunnen niet worden onderdrukt.
Suggesties voor toepassingsreacties
Hier volgt een uitsplitsing van voorgestelde oplossingen die een toepassing kan nemen op basis van welke randapparatuur(en) beperking nodig is. Het is aan de ontwikkelaar van de toepassing om te bepalen welke van deze acties een belangrijker effect kunnen hebben op elk randapparaat, omdat elke toepassing anders is. Ontwikkelaars moeten prioriteit geven aan acties die ze ondernemen op basis van de impact op de eindgebruiker.
Voorgestelde oplossingen per randapparaat
CPU
- Werkbelasting per frame aanpassen
GPU
- Renderresolutie verminderen
- De app kan vervolgens FOV (Field of View) verminderen om de wazigheid van inhoud te compenseren
- Complexiteit van scènes verminderen (aantal driehoeken en patroon)
- De verwerking van foto-/videocamera's verminderen
- Cameraresolutie verlagen
- Framesnelheid van camera verlagen
- Naverwerking van camerabeelden door apps verminderen
- Stoppen met het gebruik van de foto-/videocamera
DRAM
Netwerk
- Bandbreedte verminderen
- Framesnelheid van videogesprekken verlagen
- Netwerkactiviteit op de achtergrond stoppen (bijvoorbeeld toepassingstelemetrie)
Accu
- Overstappen op een koelere omgeving
- Apparaat zonder oplader gebruiken
- Vermijd het gebruik van een oplader met een lading van minder dan 50%
Weergave
- Het aantal zwarte pixels in de scène verhogen
- Gebruik kleuren met weinig energie (bijvoorbeeld groen)
- Het beeldscherm dimmen
Foto-/videocamera
- Overzicht
- Cameraresolutie verlagen
- Framesnelheid van camera verlagen
- Naverwerking van camerabeelden door apps verminderen
- Stoppen met het gebruik van de foto-/videocamera
Implementatiegebruiksvoorbeelden
De SDK is ontworpen ter ondersteuning van twee standaardgebruiksvoorbeelden om informatie op te halen:
- Op basis van gebeurtenissen
- Op basis van polling
Een melding op basis van gebeurtenissen biedt het snelste feedbackpad naar de toepassing voor het geval er actie moet worden ondernomen. In sommige gevallen kan het echter handiger zijn voor de ontwikkelaar om polling te gebruiken.
Notitie
Statusinformatie wordt maximaal om de paar seconden bijgewerkt voor elk randapparaat, dus het pollen sneller dan dat kan CPU-cycli verspillen.
Api-gebruik op basis van gebeurtenissen
Registreren voor gebeurtenissen
Er zijn drie vereisten om meldingen te ontvangen:
- Systeemondersteuning voor de API, inclusief het opgegeven randapparaat
- Een niet-lege eigenschap PeripheralsOfInterest
- Een niet-lege PowerThermalMitigationLevelChanged-gebeurtenis-handler of een niet-lege PowerThermalThermalScoreChanged-gebeurtenis-handler
U ontvangt geen gebeurtenissen als uw toepassing niet aan deze vereisten voldoet.
Het eerste item kan worden gecontroleerd met de functie IsSupported . Als het systeem meldingen voor ten minste één van de randapparatuur in het masker ondersteunt, retourneert de functie true. U kunt ervoor kiezen om de ondersteuning niet te controleren met behulp van deze functie, zolang uw toepassing niet expliciet afhankelijk is van PowerThermalNotification SDK-gebeurtenissen.
Zodra u aan de bovenstaande drie vereisten voldoet, ontvangt u initiële meldingen voor alle ondersteunde PeripheralsOfInterest. Als u peripheralsOfInterest of een van de gebeurtenis-handlers later wijzigt, ontvangt u een andere set meldingen op basis van de huidige status.
Hier volgt een codefragment voor het ophalen van het powerthermalnotification-klasse-exemplaar en het configureren voor meldingen voor zowel PowerThermalPeripheralFlags.Cpu alsPowerThermalPeripheralFlags.PhotoVideoCamera:
using Microsoft.MixedReality.PowerThermalNotification;
private void NotificationHandler(object sender, PowerThermalEventArgs args)
{
// Notification handling can be done here using information contained in args
}
private void InitializeThermalNotifications()
{
PowerThermalNotification p = PowerThermalNotification.GetForCurrentProcess();
PowerThermalPeripheralFlags requestedFlags = PowerThermalPeripheralFlags.Cpu | PowerThermalPeripheralFlags.PhotoVideoCamera;
if (PowerThermalNotification.IsSupported(requestedFlags))
{
//At least one of these peripherals is supported by the system
p.PeripheralsOfInterest = requestedFlags;
p.PowerThermalMitigationLevelChanged += NotificationHandler;
}
}
Gebeurtenissen verwerken
Wanneer de gebeurtenis PowerThermalMitigationLevelChanged wordt geactiveerd , wordt deze geleverd met PowerThermalEventArgs. Deze moeten worden gebruikt om de gebeurtenis te begrijpen.
Op dezelfde manier wordt de gebeurtenis PowerThermalThermalScoreChanged geleverd met PowerThermalScoreArgs.
Wanneer een gebeurtenis wordt ontvangen, moet de gebeurtenis-handler args inspecteren. ImpactedPeripherals, waarmee wordt aangegeven welke randapparatuur(en) worden beïnvloed (er kunnen meer dan één zijn).
Voor PowerThermalMitigationLevelChanged-gebeurtenissen , de argumenten. MitigationLevel geeft aan hoe ernstig een beperking wordt aanbevolen voor de opgegeven randapparatuur. Als de argumenten. MitigationLevel is PowerThermalMitigationLevel.NoUserImpact . Alle risicobeperkingen die zijn gekoppeld aan de opgegeven randapparatuur, moeten worden verwijderd.
Voor PowerThermalThermalScoreChanged-gebeurtenissen , de argumenten. ThermalScore geeft een score van 100 tot 0 aan die een lineaire schaal weergeeft die een afsluitbeurt van een toepassing nadert (nul). Het bereik van de thermische score begint buiten het bereik van de risicobeperkingsrapportage om eerdere meldingen aan de toepassing toe te staan wanneer de noodzaak van oplossingen nadert.
Hier volgt een voorbeeldhandler:
bool doCpuThrottle = false;
private void NotificationHandler(object sender, PowerThermalEventArgs args)
{
if (args.ImpactedPeripherals.HasFlag(PowerThermalPeripheralFlags.Cpu))
{
if(args.MitigationLevel = PowerThermalMitigationLevel.NoUserImpact)
{
doCpuThrottle = false;
}
else if(args.MitigationLevel >= PowerThermalMitigationLevel.MinimumUserImpact)
{
// Note that this only kicks in at MinimumUserImpact and does not get released until NoUserImpact
doCpuThrottle = true;
}
}
if (args.ImpactedPeripherals.HasFlag(PowerThermalPeripheralFlags.PhotoVideoCamera))
{
SetMitigationStatus(PhotoVideoCameraStatusText, PhotoVideoRectangle, args.MitigationLevel);
}
}
Notitie
De parameter ImpactedPeripherals van args identificeert alleen die randapparaten die zowel zijn beïnvloed als onderdeel van PeripheralsOfInterest. Andere beïnvloede randapparaten die niet zijn opgenomen in PeripheralsOfInterest, worden niet geïdentificeerd.
Notitie
Risicobeperkingsniveaus voor randapparatuur hebben hysterese. Zodra het niveau toeneemt, neemt het niet af totdat het wordt vrijgegeven. De release is een gebeurtenis met argumenten. MitigationLevel ingesteld op PowerThermalMitigationLevel.NoUserImpact.
Samenbrengen (model op basis van gebeurtenissen)
Hier volgt een eenvoudig voorbeeld van een set scripts die in Unity kan worden gebruikt om deze functionaliteit in te schakelen. De klasse NotificationComponent kan worden toegevoegd aan elk gameobject en dat gameobject kan het risicobeperkingsniveau van het toegewezen randapparaat bijhouden. De klasse NotificationManager behandelt de SDK die abonnementen beheert via het enkele exemplaar van de PowerThermalNotification-klasse .
Dit is de klasse NotificationManager:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Microsoft.MixedReality.PowerThermalNotification;
public class NotificationManager
{
private static readonly object listLock = new object();
private static List<NotificationComponent> components = new List<NotificationComponent>();
private static PowerThermalNotification p = PowerThermalNotification.GetForCurrentProcess();
private static bool FirstTime = true;
private static void NotificationHandler(object sender, PowerThermalEventArgs args)
{
lock (listLock)
{
foreach (NotificationComponent c in components)
{
UnityEngine.WSA.Application.InvokeOnAppThread(() =>
{
c.SetMitigationLevel(args.ImpactedPeripherals, args.MitigationLevel);
}, false);
}
}
}
public static void ChangeSuppression(PowerThermalPeripheralFlags peripherals, bool suppress)
{
p.SuppressPlatformMitigation(peripherals, suppress);
}
public static void AddNotification(NotificationComponent component, PowerThermalPeripheralFlags peripheralsOfInterest)
{
if (FirstTime)
{
p.PowerThermalMitigationLevelChanged += NotificationHandler;
FirstTime = false;
}
if (PowerThermalNotification.IsSupported(peripheralsOfInterest))
{
lock (listLock)
{
component.SetMitigationLevel(peripheralsOfInterest, (PowerThermalMitigationLevel)0);
components.Add(component);
}
p.PeripheralsOfInterest |= peripheralsOfInterest;
}
}
}
Dit is de klasse NotificationComponent:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Microsoft.MixedReality.PowerThermalNotification;
public class NotificationComponent : MonoBehaviour
{
//Note that this could be multiple peripherals, just need to make sure to look at impactedPeripherals in the handler
public PowerThermalPeripheralFlags monitoredPeripheral = (PowerThermalPeripheralFlags) 0;
public bool isSuppressed = false;
public void SetMitigationLevel(PowerThermalMitigationLevel level)
{
Color newColor = Color.white;
if (level == PowerThermalMitigationLevel.NoUserImpact)
{
newColor = Color.green;
}
else if (level == PowerThermalMitigationLevel.MinimumUserImpact)
{
newColor = Color.yellow;
}
else if (level == PowerThermalMitigationLevel.MediumUserImpact)
{
newColor = new Color32(255, 127, 37, 255);//Orange
}
else
{
newColor = Color.red;
}
MaterialPropertyBlock props = new MaterialPropertyBlock();
props.SetColor("_Color", newColor);
GetComponent<Renderer>().SetPropertyBlock(props);
}
public void SetMitigationLevel(PowerThermalPeripheralFlags impactedPeripherals, PowerThermalMitigationLevel level)
{
if (impactedPeripherals.HasFlag(monitoredPeripheral))
{
SetMitigationLevel(level);
}
}
void Start()
{
NotificationManager.AddNotification(this, monitoredPeripheral);
NotificationManager.ChangeSuppression(monitoredPeripheral, isSuppressed);
}
}
Api-gebruik op basis van polling
Randapparatuur van belang bijwerken
Net als bij het gebruik op basis van gebeurtenissen is het instellen van de eigenschap PeripheralsOfInterest vereist om een bepaald randapparaat te peilen.
Waarschuwing
Als u GetLastPeripheralState voor een bepaald randapparaat probeert aan te roepen zonder eerst die vlag in PeripheralsOfInterest in te stellen, wordt er een uitzondering gegenereerd. Als u GetLastPeripheralState probeert te gebruiken met een ongeldige waarde (set met meerdere vlagbits of een niet-ondersteunde bit), wordt er een uitzondering gegenereerd.
De polling-API's aanroepen
Zodra PeripheralsOfInterest de randapparaat-bit(s) heeft ingesteld die u wilt peilen, kunt u GetLastPeripheralState aanroepen.
De geretourneerde PowerThermalPeripheralState bevat de meest recente waarden voor Thermische score en Risicobeperkingsniveau voor het opgegeven randapparaat.
Notitie
Het is mogelijk dat in toekomstige platforms bepaalde randapparatuur mogelijk niet wordt ondersteund. In deze gevallen retourneert de API een thermische score van 100 en een beperkingsniveau van NoUserImpact. De toepassing kan het veld IsSupportedPeripheral van de structuur controleren om te controleren of dit het geval is voor een bepaald randapparaat.
Zie Afhandelingsgebeurtenissen voor meer informatie over de verwerking van de thermische score en mitigationlevel die worden geretourneerd door PowerThermalPeripheralState.
Hier volgt een klein fragment met polling:
private async void timerCallback(object state)
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
PowerThermalNotification p = PowerThermalNotification.GetForCurrentProcess();
PowerThermalPeripheralState CpuState = p.GetLatestPeripheralState(PowerThermalPeripheralFlags.Cpu);
PowerThermalPeripheralState PhotoVideoCameraState = p.GetLatestPeripheralState(PowerThermalPeripheralFlags.PhotoVideoCamera);
CpuScoreText.Text = CpuState.ThermalScore.ToString();
PhotoVideoScoreText.Text = PhotoVideoCameraState.ThermalScore.ToString();
});
}
private void InitializeThermalNotifications()
{
PowerThermalNotification p = PowerThermalNotification.GetForCurrentProcess();
PowerThermalPeripheralFlags requestedFlags = PowerThermalPeripheralFlags.Cpu | PowerThermalPeripheralFlags.PhotoVideoCamera;
p.SuppressedPlatformMitigationForPeripherals = requestedFlags;//Suppress any platform mitigation on CPU or PhotoVideoCamera
if (PowerThermalNotification.IsSupported(requestedFlags))
{
p.PeripheralsOfInterest = requestedFlags;
Timer timer = new Timer(timerCallback, null, 0, 3000);
}
else
{
TitleLabel.Text = "Not Supported";
}
}
Standaardsysteembeperkingen onderdrukken
Als u niet wilt dat het systeem probeert bepaalde randapparatuur te beperken, kunt u deze onderdrukken. Hiervoor werkt u de eigenschap SuppressedPlatformMitigationForPeripherals bij of roept u de functie SuppressPlatformMitigation aan.
Hier volgt een klein fragment:
PowerThermalNotification p = PowerThermalNotification.GetForCurrentProcess();
PowerThermalPeripheralFlags requestedFlags = PowerThermalPeripheralFlags.Cpu | PowerThermalPeripheralFlags.PhotoVideoCamera;
//You can do this to set the property explicitly
p.SuppressedPlatformMitigationForPeripherals = requestedFlags;
//Or you can do this to manipulate the property mask.
//This specific example clears the CPU, leaving the PhotoVideoCamera suppressed
p.SuppressPlatformMitigation(PowerThermalPeripheralFlags.Cpu, false);
Notitie
De onderdrukkings-API's werken alleen als het proces met de klasse PowerThermalNotification zich op de voorgrond bevindt. Achtergrondprocessen kunnen zich nog steeds abonneren op gebeurtenissen, maar kunnen HoloLens 2 acties mogelijk niet uitschakelen.
Testen
Zodra u de SDK in uw toepassing hebt geïntegreerd, moet u deze testen. Voor HoloLens 2 besturingssystemen die ondersteuning bieden voor de SDK, is er een ontwikkelaarspagina beschikbaar in Device Portal. Op deze pagina kunt u de risicobeperkingsniveaus en thermische scores voor elk randapparaat beheren. U kunt ook controleren welke randapparatuur beperkingen heeft die actief worden onderdrukt.
U kunt ook de REST API's gebruiken om risicobeperkingsniveaus en thermische scores van een ander apparaat te bewaken/testen. Meer informatie vindt u in de Naslaginformatie over de Device Portal-API