From db84fc713c1fb7b157e6113462ff6c5ffb77773a Mon Sep 17 00:00:00 2001 From: Arek G Date: Fri, 9 May 2025 17:58:55 +0000 Subject: [PATCH] performance: Disable ULLS if Power Hints are set to 100 (max) Related-To: NEO-14763, HSD-16026432518 Signed-off-by: Arek G --- .../sources/context/test_context.cpp | 5 ++ shared/source/os_interface/os_context.cpp | 3 +- shared/source/os_interface/os_context.h | 3 + shared/test/common/mocks/mock_os_context.h | 21 ++++++- .../os_interface/os_context_tests.cpp | 56 ++++++++++++++++++- 5 files changed, 85 insertions(+), 3 deletions(-) diff --git a/level_zero/core/test/unit_tests/sources/context/test_context.cpp b/level_zero/core/test/unit_tests/sources/context/test_context.cpp index fcfa45c9f4..4a9340d275 100644 --- a/level_zero/core/test/unit_tests/sources/context/test_context.cpp +++ b/level_zero/core/test/unit_tests/sources/context/test_context.cpp @@ -533,6 +533,11 @@ TEST_F(ContextPowerSavingHintTest, givenCallToContextCreateWithoutPowerHintDescT context->destroy(); } +TEST_F(ContextPowerSavingHintTest, givenOsContextPowerHintMaxAndZePowerSavingHintTypeMaxThenTheyAreEqualAndBothAre100) { + EXPECT_EQ(NEO::OsContext::getUmdPowerHintMax(), ZE_POWER_SAVING_HINT_TYPE_MAX); + EXPECT_EQ(NEO::OsContext::getUmdPowerHintMax(), 100u); +} + using ContextTest = Test; TEST_F(ContextTest, whenCreatingAndDestroyingContextThenSuccessIsReturned) { diff --git a/shared/source/os_interface/os_context.cpp b/shared/source/os_interface/os_context.cpp index 67ed34e7ea..a0574333c8 100644 --- a/shared/source/os_interface/os_context.cpp +++ b/shared/source/os_interface/os_context.cpp @@ -64,7 +64,8 @@ bool OsContext::ensureContextInitialized(bool allocateInterrupt) { } bool OsContext::isDirectSubmissionAvailable(const HardwareInfo &hwInfo, bool &submitOnInit) { - bool enableDirectSubmission = this->isDirectSubmissionSupported(); + bool enableDirectSubmission = this->isDirectSubmissionSupported() && + this->getUmdPowerHintValue() < NEO::OsContext::getUmdPowerHintMax(); if (debugManager.flags.SetCommandStreamReceiver.get() > 0) { enableDirectSubmission = false; diff --git a/shared/source/os_interface/os_context.h b/shared/source/os_interface/os_context.h index 063502f925..da13e652d2 100644 --- a/shared/source/os_interface/os_context.h +++ b/shared/source/os_interface/os_context.h @@ -55,6 +55,8 @@ class OsContext : public ReferenceTrackedObject { bool &startOnInit, bool &startInContext); virtual void reInitializeContext() {} + + inline static constexpr uint8_t getUmdPowerHintMax() { return NEO::OsContext::powerHintMax; } uint8_t getUmdPowerHintValue() { return powerHintValue; } void setUmdPowerHintValue(uint8_t powerHintValue) { this->powerHintValue = powerHintValue; } @@ -120,6 +122,7 @@ class OsContext : public ReferenceTrackedObject { bool contextInitialized = false; bool debuggableContext = false; uint8_t powerHintValue = 0; + static constexpr inline uint8_t powerHintMax = 100u; // by definition: 100% power-saving bool isContextGroup = false; const OsContext *primaryContext = nullptr; diff --git a/shared/test/common/mocks/mock_os_context.h b/shared/test/common/mocks/mock_os_context.h index be80619d5d..e9a78e3469 100644 --- a/shared/test/common/mocks/mock_os_context.h +++ b/shared/test/common/mocks/mock_os_context.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2023 Intel Corporation + * Copyright (C) 2019-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -32,11 +32,30 @@ class OsContextMock : public OsContext { using OsContext::engineUsage; using OsContext::getDeviceBitfield; + using OsContext::getEngineType; + using OsContext::getUmdPowerHintMax; + using OsContext::isDirectSubmissionAvailable; + using OsContext::isDirectSubmissionSupported; + using OsContext::OsContext; + using OsContext::setDefaultContext; + using OsContext::setUmdPowerHintValue; + OsContextMock(uint32_t contextId, const EngineDescriptor &engineDescriptorHelper) : OsContext(0, contextId, engineDescriptorHelper) {} uint64_t getOfflineDumpContextId(uint32_t deviceIndex) const override { return offlineDumpCtxId; }; + + bool isDirectSubmissionSupported() const override { + if (callBaseIsDirectSubmissionSupported) { + return OsContext::isDirectSubmissionSupported(); + } + return mockDirectSubmissionSupported; + } + uint64_t offlineDumpCtxId = 0; + + bool callBaseIsDirectSubmissionSupported = true; + bool mockDirectSubmissionSupported = false; }; } // namespace NEO \ No newline at end of file diff --git a/shared/test/unit_test/os_interface/os_context_tests.cpp b/shared/test/unit_test/os_interface/os_context_tests.cpp index 198f6cb4c5..c40a6269cb 100644 --- a/shared/test/unit_test/os_interface/os_context_tests.cpp +++ b/shared/test/unit_test/os_interface/os_context_tests.cpp @@ -1,16 +1,18 @@ /* - * Copyright (C) 2019-2024 Intel Corporation + * Copyright (C) 2019-2025 Intel Corporation * * SPDX-License-Identifier: MIT * */ +#include "shared/source/helpers/hw_info.h" #include "shared/source/os_interface/device_factory.h" #include "shared/source/os_interface/os_context.h" #include "shared/test/common/helpers/debug_manager_state_restore.h" #include "shared/test/common/helpers/default_hw_info.h" #include "shared/test/common/helpers/engine_descriptor_helper.h" #include "shared/test/common/mocks/mock_device.h" +#include "shared/test/common/mocks/mock_os_context.h" #include "gtest/gtest.h" @@ -81,6 +83,58 @@ TEST(OSContext, givenSetPowerHintThenGetPowerHintShowsTheSameValue) { delete pOsContext; } +TEST(OSContext, givenPowerHintSetToMaxWhenCheckingDirectSubmissionAvailabilityThenFalseIsReturnedUnlessDebugFlagEnableDirectSubmissionTrue) { + auto engineDescriptor = EngineDescriptorHelper::getDefaultDescriptor(); + auto pOsContext = std::make_unique(0, 0, engineDescriptor); + ASSERT_NE(pOsContext, nullptr); + pOsContext->callBaseIsDirectSubmissionSupported = false; + pOsContext->mockDirectSubmissionSupported = true; + pOsContext->setDefaultContext(true); + ASSERT_NE(defaultHwInfo, nullptr); + auto hwInfo = *defaultHwInfo; + hwInfo.capabilityTable.directSubmissionEngines.data[pOsContext->getEngineType()] + .engineSupported = true; + bool submitOnInit = false; + + pOsContext->setUmdPowerHintValue(OsContextMock::getUmdPowerHintMax()); + EXPECT_FALSE(pOsContext->isDirectSubmissionAvailable(hwInfo, submitOnInit)); + pOsContext->setUmdPowerHintValue(OsContextMock::getUmdPowerHintMax() / 2); + EXPECT_TRUE(pOsContext->isDirectSubmissionAvailable(hwInfo, submitOnInit)); + + DebugManagerStateRestore debugFlagsStateRestorer; + { + debugManager.flags.EnableDirectSubmission.set(-1); // only in this case second/csr flag have any significance here + { + debugManager.flags.SetCommandStreamReceiver.set(0); // as representation of values <= 0 + pOsContext->setUmdPowerHintValue(OsContextMock::getUmdPowerHintMax()); + EXPECT_FALSE(pOsContext->isDirectSubmissionAvailable(hwInfo, submitOnInit)); + pOsContext->setUmdPowerHintValue(OsContextMock::getUmdPowerHintMax() / 2); + EXPECT_TRUE(pOsContext->isDirectSubmissionAvailable(hwInfo, submitOnInit)); + } + { + debugManager.flags.SetCommandStreamReceiver.set(1); // as representation of values > 0 + pOsContext->setUmdPowerHintValue(OsContextMock::getUmdPowerHintMax()); + EXPECT_FALSE(pOsContext->isDirectSubmissionAvailable(hwInfo, submitOnInit)); + pOsContext->setUmdPowerHintValue(OsContextMock::getUmdPowerHintMax() / 2); + EXPECT_FALSE(pOsContext->isDirectSubmissionAvailable(hwInfo, submitOnInit)); + } + } + { + debugManager.flags.EnableDirectSubmission.set(0); + pOsContext->setUmdPowerHintValue(OsContextMock::getUmdPowerHintMax()); + EXPECT_FALSE(pOsContext->isDirectSubmissionAvailable(hwInfo, submitOnInit)); + pOsContext->setUmdPowerHintValue(OsContextMock::getUmdPowerHintMax() / 2); + EXPECT_FALSE(pOsContext->isDirectSubmissionAvailable(hwInfo, submitOnInit)); + } + { + debugManager.flags.EnableDirectSubmission.set(1); + pOsContext->setUmdPowerHintValue(OsContextMock::getUmdPowerHintMax()); + EXPECT_TRUE(pOsContext->isDirectSubmissionAvailable(hwInfo, submitOnInit)); + pOsContext->setUmdPowerHintValue(OsContextMock::getUmdPowerHintMax() / 2); + EXPECT_TRUE(pOsContext->isDirectSubmissionAvailable(hwInfo, submitOnInit)); + } +} + TEST(OSContext, givenOsContextWhenQueryingForOfflineDumpContextIdThenCorrectValueIsReturned) { OsContext *osContext = OsContext::create(nullptr, 0, 0, EngineDescriptorHelper::getDefaultDescriptor()); EXPECT_EQ(0u, osContext->getOfflineDumpContextId(0));