전력 및 열 관리

HoloLens 2 웜 환경에서 실행 중이거나 성능 요구 사항(CPU/GPU 사용량, 주변 장치 사용 등)이 많은 경우 과열을 막기 위해 자동으로 작업을 수행할 정도로 뜨거워질 수 있습니다. 이러한 작업에는 다음과 같은 작업이 포함됩니다.

  • 충전 성능 조정
  • 사용자 피드백 제공
  • 애플리케이션 닫기

... 최악의 시나리오에서 다음을 수행합니다.

  • HoloLens 2 종료

애플리케이션에 높은 주변 장치 성능이 요구되는 경우 PowerThermalNotification SDK(소프트웨어 개발 키트)를 사용하여 알림 이벤트를 구독하고 고유한 사용자 지정 작업을 구현하는 것이 좋습니다. 이렇게 하면 시스템에서 애플리케이션을 종료할 수 있는 상황에서 디바이스가 더 오래 작동할 수 있습니다.

참고

Microsoft.MixedReality.PowerThermalNotification SDK에 대한 지원은 22H1 릴리스에 포함되어 있습니다.

이 문서에서는 PowerThermalNotification SDK 및 시작하기 위한 기본 사용에 대해 설명합니다.

SDK는 어디에서 얻을 수 있나요?

PowerThermalNotification SDK는 Mixed Reality 기능 도구를 통해 다운로드할 수 있습니다.

PowerThermalNotification SDK는 개발자가 Win32 또는 UWP 플랫폼용 애플리케이션을 개발할 수 있도록 C# 및 C++에 대한 언어 프로젝션을 지원합니다.

개념적 개요

HoloLens 2 사용하는 전력은 열에서 소멸됩니다. 기존 PC 장치에는 이 문제를 해결하기 위한 팬이 있지만 웨어러블 디바이스는 경량이어야 합니다. 이 때문에 냉각 솔루션은 더 복잡합니다. HoloLens 2 헤드셋이 사용자에게 너무 뜨거워지지 않도록 하드웨어 및 소프트웨어 안전 기능이 내장되어 있지만 이러한 기능도 사용자 환경과 균형을 유지해야 합니다. 예를 들어 HoloLens 2 어느 부분이 가열되는지 알고 있는 경우 이 열에 대한 책임이 있는 주변 장치를 제한하도록 선택할 수 있습니다. 최후의 수단으로, 우리는이 열로 이어진 힘에 대한 책임이 있다고 생각되는 응용 프로그램을 닫을 수 있습니다.

HoloLens 2 온도 센서를 사용하여 열 문제를 처리합니다. 열 프레임워크는 센서 그룹을 디바이스의 다른 주변 장치에 연결합니다. 센서는 HoloLens 2 가열하는 전력 그리기를 담당하는 물리적 영역의 주변 장치를 결정하는 것이 불가능할 수 있기 때문에 그룹화됩니다.

PowerThermalNotification SDK는 이러한 센서 그룹을 모니터링하는 데 필요한 API를 노출합니다. SDK 이벤트는 애플리케이션에서 사용하는 주변 장치가 완화가 필요할 수 있다는 징후를 표시할 때 발생합니다. 그러면 애플리케이션이 고객 환경을 조정하여 열 영향을 줄일 수 있습니다. 영향을 줄이면 애플리케이션 또는 디바이스 종료와 같은 시스템 작업의 위험이 줄어듭니다.

간단한 예제는 CPU를 사용하여 많은 양의 비디오 데이터를 처리하는 애플리케이션입니다. 애플리케이션은 CPU 구성 요소에 대한 성능 알림을 구독할 수 있습니다. 애플리케이션이 알림을 받으면 CPU 워크로드를 줄일 수 있습니다. 추가 완화가 필요하지 않음을 나타내는 다른 이벤트가 수신되면 CPU 워크로드를 복원할 수 있습니다.

플랫폼 응답

다음 표는 주변 장치별 시스템 작업의 분석입니다. 아래에 설명된 작업은 SDK를 사용하여 표시하지 않을 수 있습니다. 기본 시스템 완화 표시 안 함을 참조하세요.

주변 장치 MinimumUserImpact MediumUserImpact MaximumUserImpact 라스트 리조트 소프트웨어 종료 Failsafe
GPU MRC 품질
조정 VSYNC 간격 제한
표시 깊이 FPS 감소
모든 주변 장치 표시 경고
닫기 애플리케이션
MRC 캡처 중지
OS 종료 하드웨어 종료

참고

"Last Resort", "Software Shutdown" 및 "Failsafe" 열의 작업은 억제할 수 없습니다.

애플리케이션 응답에 대한 제안

다음은 완화가 필요한 주변 장치에 따라 애플리케이션이 취할 수 있는 제안된 완화를 분석한 것입니다. 모든 애플리케이션이 다르기 때문에 이러한 작업 중 각 주변 장치에 더 큰 영향을 미칠 수 있는 작업은 애플리케이션 개발자에게 달려 있습니다. 개발자는 최종 사용자에게 미치는 영향에 따라 수행하는 작업의 우선 순위를 지정해야 합니다.

주변 장치별 제안된 완화

CPU

GPU

DRAM

네트워크

배터리

표시

사진/비디오 카메라

  • 개요
  • 카메라 해상도 줄이기
  • 카메라 프레임 속도 감소
  • 카메라 이미지의 앱 후처리 줄이기
  • 사진/비디오 카메라 사용 중지

구현 사용 사례

SDK는 다음 두 가지 표준 사용 사례를 지원하여 정보를 얻도록 설계되었습니다.

  • 이벤트 기반
  • 폴링 기반

이벤트 기반 알림은 작업을 수행해야 하는 경우 애플리케이션에 대한 가장 빠른 피드백 경로를 제공합니다. 그러나 경우에 따라 개발자가 폴링을 사용하는 것이 더 편리할 수 있습니다.

참고

상태 정보는 각 주변 기기에 대해 최대 몇 초마다 업데이트되므로 CPU 주기를 낭비할 수 있는 것보다 더 빠르게 폴링합니다.

이벤트 기반 API 사용량

이벤트 등록

알림을 받으려면 다음 세 가지 요구 사항이 있습니다.

애플리케이션이 이러한 요구 사항을 충족하지 않으면 이벤트를 수신하지 않습니다.

첫 번째 항목은 IsSupported 함수를 사용하여 확인할 수 있습니다. 시스템에서 마스크의 주변 장치 중 하나 이상에 대한 알림을 지원하는 경우 함수는 true를 반환합니다. 애플리케이션이 PowerThermalNotification SDK 이벤트에 명시적으로 의존하지 않는 한 이 함수를 사용하여 검사 지원하지 않도록 선택할 수 있습니다.

위의 세 가지 요구 사항을 충족하면 지원되는 모든 PeripheralsOfInterest에 대한 초기 알림을 받게 됩니다. 나중에 PeripheralsOfInterest 또는 이벤트 처리기 중 하나를 변경하는 경우 현재 상태 따라 다른 알림 집합을 받게 됩니다.

다음은 PowerThermalNotification 클래스 instance 잡고 PowerThermalPeripheralFlags.CpuPowerThermalPeripheralFlags.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;
    }  
}

이벤트 처리

PowerThermalMitigationLevelChanged 이벤트가 발생하면 PowerThermalEventArgs와 함께 제공됩니다. 이벤트를 이해하는 데 사용해야 합니다.

마찬가지로 PowerThermalThermalScoreChanged 이벤트가 발생하면 PowerThermalScoreArgs와 함께 제공됩니다.

이벤트가 수신되면 이벤트 처리기는 인수를 검사해야 합니다 . ImpactedPeripherals - 영향을 받을 주변 장치를 식별합니다(둘 이상이 있을 수 있음).

PowerThermalMitigationLevelChanged 이벤트의 경우 인수입니다. MitigationLevel은 지정된 주변 디바이스에 대해 완화가 얼마나 심각한지 나타냅니다. 인수인 경우 MitigationLevelPowerThermalMitigationLevel.NoUserImpact인 경우 지정된 주변 장치와 연결된 모든 완화를 제거해야 합니다.

PowerThermalThermalScoreChanged 이벤트의 경우 인수입니다. ThermalScore는 애플리케이션 종료 이벤트(0)에 접근하는 선형 배율을 반영하는 100에서 0까지의 점수를 나타냅니다. 열 점수 범위는 완화의 필요성에 접근할 때 애플리케이션에 대한 이전 알림을 허용하기 위해 완화 보고 범위 외부에서 시작됩니다.

예제 처리기는 다음과 같습니다.

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

참고

인수의 ImpactedPeripherals 매개 변수는 PeripheralsOfInterest의 영향을 받은 주변 장치만 식별합니다. PeripheralsOfInterest에 포함되지 않은 다른 영향을 받은 주변 장치는 식별되지 않습니다.

참고

주변 기기에 대한 완화 수준에는 hysteresis가 있습니다. 수준이 증가하면 릴리스될 때까지 감소하지 않습니다. 릴리스는 인수가 있는 이벤트입니다. MitigationLevel을 PowerThermalMitigationLevel.NoUserImpact로 설정합니다.

함께 배치(이벤트 기반 모델)

다음은 Unity에서 이 기능을 사용하도록 설정하는 데 사용할 수 있는 스크립트 집합의 간단한 예입니다. NotificationComponent 클래스를 모든 게임 개체에 추가할 수 있으며 해당 게임 개체는 할당된 주변 디바이스의 완화 수준을 추적할 수 있습니다. NotificationManager 클래스는 PowerThermalNotification 클래스의 단일 instance 통해 구독을 관리하는 SDK를 처리합니다.

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

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 사용량

관심 있는 주변 장치 업데이트

이벤트 기반 사용과 마찬가지로 지정된 주변 장치를 폴링하려면 PeripheralsOfInterest 속성을 설정해야 합니다.

경고

PeripheralsOfInterest에서 플래그를 먼저 설정하지 않고 지정된 주변 디바이스에 대해 GetLastPeripheralState를 호출하려고 하면 예외가 throw됩니다. 마찬가지로 잘못된 값(여러 플래그 비트 집합 또는 지원되지 않는 비트)과 함께 GetLastPeripheralState 를 사용하려고 하면 예외가 throw됩니다.

폴링 API 호출

PeripheralsOfInterest에 폴링하려는 주변 장치 비트 집합이 있으면 GetLastPeripheralState를 호출할 수 있습니다.

반환된 PowerThermalPeripheralState 에는 지정된 주변 장치에 대한 열 점수 및 완화 수준에 대한 최신 값이 포함되어 있습니다.

참고

향후 플랫폼에서 특정 주변 장치가 지원되지 않을 수 있습니다. 이러한 경우 API는 열 점수 100과 NoUserImpact의 완화 수준을 반환합니다. 애플리케이션은 구조체의 IsSupportedPeripheral 필드를 검사 지정된 주변 디바이스의 경우인지 여부를 검사 수 있습니다.

PowerThermalPeripheralState에서 반환된 열 점수MitigationLevel의 처리에 대한 자세한 내용은 이벤트 처리를 참조하세요.

다음은 폴링을 보여 주는 작은 코드 조각입니다.

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

기본 시스템 완화 표시 안 함

시스템이 특정 주변 장치를 완화하려고 시도하지 않으려면 이를 표시하지 않을 수 있습니다. 이렇게 하려면 SuppressedPlatformMitigationForPeripherals 속성을 업데이트하거나 SuppressPlatformMitigation 함수를 호출하면 됩니다.

작은 코드 조각은 다음과 같습니다.

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

참고

비표시 API는 PowerThermalNotification 클래스를 사용하는 프로세스가 포그라운드에 있는 경우에만 작동합니다. 백그라운드 프로세스는 여전히 이벤트를 구독할 수 있지만 HoloLens 2 작업을 사용하지 않도록 설정할 수 없습니다.

테스트

SDK를 애플리케이션에 통합한 후에는 테스트하려고 합니다. SDK를 지원하는 HoloLens 2 운영 체제의 경우 디바이스 포털에서 개발자 페이지를 사용할 수 있습니다. 이 페이지에서는 각 주변 기기에 대한 완화 수준 및 열 점수를 제어할 수 있습니다. 완화가 적극적으로 억제되는 주변 장치를 모니터링할 수도 있습니다.

REST API를 활용하여 다른 디바이스의 완화 수준 및 열 점수를 모니터링/테스트할 수도 있습니다. 자세한 내용은 디바이스 포털 API 참조에서 찾을 수 있습니다.