Administración de energía y térmicas

Cuando el HoloLens 2 se ejecuta en entornos semiactivos o con requisitos de rendimiento intensivos (uso de CPU/GPU, uso periférico, etc.), es posible que se caliente lo suficiente como para realizar acciones automáticamente para evitar el sobrecalentamiento. Estas acciones incluyen cosas como:

  • Ajuste del rendimiento de la carga
  • Proporcionar comentarios de los usuarios
  • Cierre de aplicaciones

... y en los peores escenarios:

  • Apagar el HoloLens 2

Si la aplicación requiere un alto rendimiento periférico, considere la posibilidad de usar el Kit de desarrollo de software (SDK) de PowerThermalNotification para suscribirse a eventos de notificación e implementar sus propias acciones personalizadas. Si lo hace, el sistema puede permitir que el dispositivo funcione más tiempo en situaciones en las que, de lo contrario, el sistema puede terminar una aplicación.

Nota

La compatibilidad con el SDK Microsoft.MixedReality.PowerThermalNotification se incluye en la versión 22H1.

En este artículo se describe el SDK de PowerThermalNotification y su uso básico para empezar.

¿Dónde obtengo el SDK?

El SDK de PowerThermalNotification se puede descargar a través de Mixed Reality Feature Tool.

El SDK de PowerThermalNotification admite proyecciones de lenguaje para C# y C++, lo que permite a los desarrolladores desarrollar aplicaciones para plataformas Win32 o UWP.

Información general conceptual

La potencia consumida por el HoloLens 2 se disipa en calor. Un dispositivo pc tradicional tendría un ventilador para abordar esto, pero un dispositivo portátil debe ser ligero. Por este motivo, la solución de refrigeración es más compleja. HoloLens 2 tiene características integradas de seguridad de hardware y software para garantizar que los auriculares no estén demasiado calientes para el usuario, pero estas características también deben equilibrarse con la experiencia del usuario. Por ejemplo, si sabemos qué parte del HoloLens 2 se está calientando, podemos optar por limitar los periféricos responsables de este calor. Como último recurso, podríamos cerrar una aplicación que se cree que es responsable de la potencia que llevó a este calor.

HoloLens 2 controla los problemas de calor mediante sensores de temperatura. Un marco térmico vincula grupos de sensores a diferentes periféricos del dispositivo. Los sensores se agrupan porque puede ser imposible determinar qué periférico en un área física es responsable del consumo de energía que calienta la HoloLens 2.

El SDK de PowerThermalNotification expone las API necesarias para supervisar estos grupos de sensores. Los eventos del SDK se activan cuando un periférico que usa la aplicación muestra signos de que se puede requerir una mitigación. Después, la aplicación puede adaptar su experiencia del cliente para reducir el impacto térmico. Reducir el impacto significa menos riesgo de acción del sistema, como el apagado de la aplicación o del dispositivo.

Un ejemplo sencillo sería una aplicación que usa la CPU para procesar una gran cantidad de datos de vídeo. La aplicación podría suscribirse a una notificación de rendimiento para el componente de CPU. Cuando la aplicación recibe una notificación, puede reducir la carga de trabajo de CPU. Si se recibe otro evento que indica que no es necesaria ninguna mitigación adicional, se puede restaurar la carga de trabajo de CPU.

Respuesta de la plataforma

La tabla siguiente es un desglose de las acciones del sistema por periféricos. Las acciones que se describen a continuación se pueden suprimir mediante el SDK. Consulte Suprimir mitigaciones predeterminadas del sistema.

Periférico MinimumUserImpact MediumUserImpact MaximumUserImpact Last Resort Apagado de software Failsafe
GPU Limitación del intervalo de ajuste de calidad
de MRC VSYNC
Mostrar Reducción de FPS de profundidad
Cualquier periférico Mostrar advertencia
Cerrar la captura de MRC de la aplicación
Apagado del sistema operativo Apagado de hardware

Nota

Las acciones de las columnas "Last Resort", "Software Shutdown" y "Failsafe" no se pueden suprimir.

Sugerencias para la respuesta de la aplicación

A continuación se muestra un desglose de las mitigaciones sugeridas que una aplicación puede adoptar en función de qué periféricos necesitan mitigación. Depende del desarrollador de aplicaciones determinar cuál de estas acciones puede tener un efecto más significativo en cada periférico, ya que cada aplicación es diferente. Los desarrolladores deben priorizar las acciones que realizan en función del impacto en el usuario final.

Mitigaciones sugeridas por periféricos

CPU

GPU

DRAM

Red

Batería

Mostrar

  • Aumentar el número de píxeles negros en la escena
  • Usar colores de bajo consumo (por ejemplo, verde)
  • Atenuar la pantalla

Cámara de fotos y vídeo

  • Información general
  • Reducir la resolución de la cámara
  • Reducir la velocidad de fotogramas de la cámara
  • Reducir el posprocesamiento de las imágenes de cámara de la aplicación
  • Dejar de usar la cámara de fotos y vídeos

Casos de uso de implementación

El SDK está diseñado para admitir dos casos de uso estándar para obtener información:

  • Basada en evento
  • Basado en sondeos

La notificación basada en eventos proporcionará la ruta de acceso de comentarios más rápida a la aplicación en caso de que tenga que tomar medidas. Sin embargo, en algunos casos puede ser más conveniente para que el desarrollador use el sondeo.

Nota

La información de estado se actualiza, como máximo, cada pocos segundos para cada periférico, por lo que sondea más rápido que eso puede perder ciclos de CPU.

Uso de la API basada en eventos

Registro de eventos

Para obtener notificaciones, hay tres requisitos:

No recibirá eventos si la aplicación no cumple estos requisitos.

El primer elemento se puede comprobar mediante la función IsSupported . Si el sistema admite notificaciones para al menos uno de los periféricos de la máscara, la función devolverá true. Puede optar por no comprobar la compatibilidad con esta función siempre y cuando la aplicación no dependa explícitamente de los eventos del SDK de PowerThermalNotification.

Una vez que cumpla los tres requisitos anteriores, recibirá notificaciones iniciales para todos los periféricos compatibles DeInterest. Si posteriormente cambias PeripheralsOfInterest o alguno de los controladores de eventos, recibirás otro conjunto de notificaciones en función del estado actual.

Este es un fragmento de código para capturar la instancia de la clase PowerThermalNotification y configurarla para las notificaciones de PowerThermalPeripheralFlags.Cpu y PowerThermalPeripheralFlags.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;
    }  
}

Control de eventos

Cuando se desencadena el evento PowerThermalMitigationLevelChanged , viene con PowerThermalEventArgs. Se deben usar para comprender el evento.

Del mismo modo, cuando se desencadena el evento PowerThermalThermalScoreChanged , viene con PowerThermalScoreArgs.

Cuando se recibe un evento, el controlador de eventos debe inspeccionar argumentos. ImpactedPeripherals, que identifica qué periféricos se ven afectados (puede haber más de uno).

Para los eventos PowerThermalMitigationLevelChanged , los argumentos. MitigationLevel indica la gravedad de una mitigación recomendada para los periféricos especificados. Si los argumentos. MitigationLevel es PowerThermalMitigationLevel.NoUserImpact y, a continuación, se deben quitar las mitigaciones asociadas a los periféricos especificados.

Para los eventos PowerThermalThermalScoreChanged , los argumentos. ThermalScore indica una puntuación de 100 a 0 que refleja una escala lineal que se aproxima a un evento de apagado de la aplicación (cero). El intervalo de puntuación térmica comienza fuera del intervalo de informes de mitigación para permitir una notificación anterior a la aplicación cuando se aproxima a la necesidad de mitigaciones.

Este es un controlador de ejemplo:

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);
    }
}

Nota

El parámetro ImpactedPeripherals de args solo identifica los periféricos que se vieron afectados y que formaban parte de PeripheralsOfInterest. No se identificarán otros periféricos afectados que no se incluyeron en PeripheralsOfInterest.

Nota

Los niveles de mitigación para periféricos tienen histéresis. Una vez que el nivel aumenta, no disminuye hasta que se libera. La versión es un evento con argumentos. MitigationLevel establecido en PowerThermalMitigationLevel.NoUserImpact.

Reunirlo (modelo basado en eventos)

Este es un ejemplo sencillo de un conjunto de scripts que se pueden usar en Unity para habilitar esta funcionalidad. La clase NotificationComponent se puede agregar a cualquier objeto de juego y ese objeto de juego puede realizar un seguimiento del nivel de mitigación del periférico asignado. La clase NotificationManager trata con el SDK que administra las suscripciones a través de la única instancia de la clase PowerThermalNotification .

Esta es la clase 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;
        }
    }
}

Esta es la clase 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);
    }

}

Uso de la API basada en sondeo

Actualización de periféricos de interés

De forma similar al uso basado en eventos, es necesario establecer la propiedad PeripheralsOfInterest para sondear un periférico determinado.

Advertencia

Si intenta llamar a GetLastPeripheralState para un periférico determinado sin establecer primero esa marca en PeripheralsOfInterest, se producirá una excepción. Del mismo modo, si intenta usar GetLastPeripheralState con un valor no válido (varios bits de marca establecidos o un bit no admitido), se producirá una excepción.

Llamada a las API de sondeo

Una vez que PeripheralsOfInterest tiene los bits periféricos establecidos que desea sondear, puede llamar a GetLastPeripheralState.

PowerThermalPeripheralState devuelto contiene los valores más recientes de Puntuación térmica y Nivel de mitigación para el periférico especificado.

Nota

Es posible que en plataformas futuras, es posible que no se admita ciertos periféricos. En estos casos, la API devolverá una puntuación térmica de 100 y un nivel de mitigación de NoUserImpact. La aplicación puede comprobar el campo IsSupportedPeripheral de la estructura para comprobar si este es el caso de un periférico determinado.

Consulte Control de eventos para obtener más información sobre el control de la puntuación térmica y mitigationLevel devuelto por PowerThermalPeripheralState.

Este es un pequeño fragmento de código que muestra el sondeo:

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";
    }
}

Supresión de mitigaciones predeterminadas del sistema

Si no desea que el sistema intente mitigar determinados periféricos, puede suprimirlos. Para ello, actualice la propiedad SuppressedPlatformMitigationForPeripherals o llame a la función SuppressPlatformMitigation .

Este es un pequeño fragmento de código:

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);

Nota

Las API de supresión solo funcionarán si el proceso que usa la clase PowerThermalNotification está en primer plano. Los procesos en segundo plano todavía se pueden suscribir a eventos, pero es posible que no deshabiliten HoloLens 2 acciones.

Prueba

Una vez que haya integrado el SDK en la aplicación, querrá probarlo. Para HoloLens 2 sistemas operativos que admiten el SDK, una página para desarrolladores estará disponible en Device Portal. Desde esta página, puede controlar los niveles de mitigación y las puntuaciones térmicas de cada periférico. También puede supervisar qué periféricos tienen mitigaciones que se suprimen activamente.

También puede aprovechar las API REST para supervisar o probar los niveles de mitigación y las puntuaciones térmicas de otro dispositivo. Puede encontrar más información en la referencia de api de Device Portal.