performance: debug key for adjust ULLS on battery

ULLS controller timeout settings will be adjusted based on ac line
status and lowest queue throttle from submissions.

Lowest queue throttle is reset when controller stops ULLS.

Related-To: NEO-10800

Signed-off-by: Dominik Dabek <dominik.dabek@intel.com>
This commit is contained in:
Dominik Dabek
2024-03-22 11:18:35 +00:00
committed by Compute-Runtime-Automation
parent ec19ce536a
commit 2b964254d6
23 changed files with 365 additions and 33 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2023 Intel Corporation
* Copyright (C) 2018-2024 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -9,6 +9,7 @@
#include "shared/source/os_interface/os_context.h"
#include "shared/test/common/helpers/debug_manager_state_restore.h"
#include "shared/test/common/mocks/mock_device.h"
#include "shared/test/common/mocks/mock_kmd_notify_helper.h"
#include "shared/test/common/test_macros/hw_test.h"
#include "opencl/source/command_queue/command_queue.h"
@@ -45,30 +46,6 @@ struct KmdNotifyTests : public ::testing::Test {
properties.delayQuickKmdSleepForDirectSubmissionMicroseconds = quickKmdSleepDelayForDirectSubmission;
}
class MockKmdNotifyHelper : public KmdNotifyHelper {
public:
using KmdNotifyHelper::acLineConnected;
using KmdNotifyHelper::getMicrosecondsSinceEpoch;
using KmdNotifyHelper::lastWaitForCompletionTimestampUs;
using KmdNotifyHelper::properties;
MockKmdNotifyHelper() = delete;
MockKmdNotifyHelper(const KmdNotifyProperties *newProperties) : KmdNotifyHelper(newProperties){};
void updateLastWaitForCompletionTimestamp() override {
KmdNotifyHelper::updateLastWaitForCompletionTimestamp();
updateLastWaitForCompletionTimestampCalled++;
}
void updateAcLineStatus() override {
KmdNotifyHelper::updateAcLineStatus();
updateAcLineStatusCalled++;
}
uint32_t updateLastWaitForCompletionTimestampCalled = 0u;
uint32_t updateAcLineStatusCalled = 0u;
};
template <typename Family>
class MockKmdNotifyCsr : public UltCommandStreamReceiver<Family> {
public:

View File

@@ -616,6 +616,10 @@ class CommandStreamReceiverMock : public CommandStreamReceiver {
void postInitFlagsSetup() override {}
SubmissionStatus initializeDeviceWithFirstSubmission(Device &device) override { return SubmissionStatus::success; }
QueueThrottle getLastDirectSubmissionThrottle() override {
return QueueThrottle::MEDIUM;
}
std::map<const void *, size_t> residency;
std::unique_ptr<ExecutionEnvironment> mockExecutionEnvironment;
bool passResidencyCallToBaseClass = true;

View File

@@ -634,6 +634,7 @@ void CommandStreamReceiver::downloadAllocation(GraphicsAllocation &gfxAllocation
void CommandStreamReceiver::startControllingDirectSubmissions() {
auto controller = this->executionEnvironment.directSubmissionController.get();
if (controller) {
controller->setTimeoutParamsForPlatform(this->getProductHelper());
controller->startControlling();
}
}

View File

@@ -13,6 +13,7 @@
#include "shared/source/helpers/cache_policy.h"
#include "shared/source/helpers/common_types.h"
#include "shared/source/helpers/completion_stamp.h"
#include "shared/source/helpers/kmd_notify_properties.h"
#include "shared/source/helpers/options.h"
#include "shared/source/utilities/spinlock.h"
@@ -323,6 +324,8 @@ class CommandStreamReceiver {
virtual void stopDirectSubmission(bool blocking) {}
virtual QueueThrottle getLastDirectSubmissionThrottle() = 0;
bool isStaticWorkPartitioningEnabled() const {
return staticWorkPartitioningEnabled;
}
@@ -460,6 +463,13 @@ class CommandStreamReceiver {
return this->resourcesInitialized;
}
MOCKABLE_VIRTUAL bool getAcLineConnected(bool updateStatus) const {
if (updateStatus) {
this->kmdNotifyHelper->updateAcLineStatus();
}
return this->kmdNotifyHelper->getAcLineConnected();
}
uint32_t getRequiredScratchSlot0Size() { return requiredScratchSlot0Size; }
uint32_t getRequiredScratchSlot1Size() { return requiredScratchSlot1Size; }

View File

@@ -156,6 +156,8 @@ class CommandStreamReceiverHw : public CommandStreamReceiver {
void stopDirectSubmission(bool blocking) override;
QueueThrottle getLastDirectSubmissionThrottle() override;
virtual bool isKmdWaitModeActive() { return true; }
bool initDirectSubmission() override;

View File

@@ -1362,6 +1362,18 @@ inline void CommandStreamReceiverHw<GfxFamily>::stopDirectSubmission(bool blocki
}
}
template <typename GfxFamily>
inline QueueThrottle CommandStreamReceiverHw<GfxFamily>::getLastDirectSubmissionThrottle() {
if (this->isAnyDirectSubmissionEnabled()) {
if (EngineHelpers::isBcs(this->osContext->getEngineType())) {
return this->blitterDirectSubmission->getLastSubmittedThrottle();
} else {
return this->directSubmission->getLastSubmittedThrottle();
}
}
return QueueThrottle::MEDIUM;
}
template <typename GfxFamily>
inline bool CommandStreamReceiverHw<GfxFamily>::initDirectSubmission() {
bool ret = true;

View File

@@ -402,6 +402,7 @@ DECLARE_DEBUG_VARIABLE(int32_t, EnableDirectSubmissionController, -1, "Enable di
DECLARE_DEBUG_VARIABLE(int32_t, DirectSubmissionControllerTimeout, -1, "Set direct submission controller timeout, -1: default 5000 us, >=0: timeout in us")
DECLARE_DEBUG_VARIABLE(int32_t, DirectSubmissionControllerMaxTimeout, -1, "Set direct submission controller max timeout - timeout will increase up to given value, -1: default 5000 us, >=0: max timeout in us")
DECLARE_DEBUG_VARIABLE(int32_t, DirectSubmissionControllerDivisor, -1, "Set direct submission controller timeout divider, -1: default 1, >0: divider value")
DECLARE_DEBUG_VARIABLE(int32_t, DirectSubmissionControllerAdjustOnThrottleAndAcLineStatus, -1, "Adjust controller timeout settings based on queue throttle and ac line status, -1: default, 0: disabled, 1: enabled")
DECLARE_DEBUG_VARIABLE(int32_t, DirectSubmissionForceLocalMemoryStorageMode, -1, "Force local memory storage for command/ring/semaphore buffer, -1: default - for all engines, 0: disabled, 1: for multiOsContextCapable engine, 2: for all engines")
DECLARE_DEBUG_VARIABLE(int32_t, EnableRingSwitchTagUpdateWa, -1, "-1: default, 0 - disable, 1 - enable. If enabled, completionFences wont be updated if ring is not running.")
DECLARE_DEBUG_VARIABLE(int32_t, DirectSubmissionPCIBarrier, -1, "Use PCI barrier for data synchronization before semaphore unblock -1: default, 0 - disable, 1 - enable.")

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2019-2023 Intel Corporation
* Copyright (C) 2019-2024 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -11,6 +11,7 @@
#include "shared/source/debug_settings/debug_settings_manager.h"
#include "shared/source/os_interface/os_context.h"
#include "shared/source/os_interface/os_thread.h"
#include "shared/source/os_interface/product_helper.h"
#include <chrono>
#include <thread>
@@ -28,6 +29,10 @@ DirectSubmissionController::DirectSubmissionController() {
maxTimeout = std::chrono::microseconds{debugManager.flags.DirectSubmissionControllerMaxTimeout.get()};
}
if (debugManager.flags.DirectSubmissionControllerAdjustOnThrottleAndAcLineStatus.get() != -1) {
adjustTimeoutOnThrottleAndAcLineStatus = debugManager.flags.DirectSubmissionControllerAdjustOnThrottleAndAcLineStatus.get();
}
directSubmissionControllingThread = Thread::create(controlDirectSubmissionsState, reinterpret_cast<void *>(this));
};
@@ -45,6 +50,33 @@ void DirectSubmissionController::registerDirectSubmission(CommandStreamReceiver
this->adjustTimeout(csr);
}
void DirectSubmissionController::setTimeoutParamsForPlatform(const ProductHelper &helper) {
for (auto throttle : {QueueThrottle::LOW, QueueThrottle::MEDIUM, QueueThrottle::HIGH}) {
for (auto acLineStatus : {false, true}) {
auto key = this->getTimeoutParamsMapKey(throttle, acLineStatus);
auto timeoutParam = std::make_pair(key, helper.getDirectSubmissionControllerTimeoutParams(acLineStatus, throttle));
this->timeoutParamsMap.insert(timeoutParam);
}
}
}
void DirectSubmissionController::applyTimeoutForAcLineStatusAndThrottle(bool acLineConnected) {
const auto &timeoutParams = this->timeoutParamsMap[this->getTimeoutParamsMapKey(this->lowestThrottleSubmitted, acLineConnected)];
this->timeout = timeoutParams.timeout;
this->maxTimeout = timeoutParams.maxTimeout;
this->timeoutDivisor = timeoutParams.timeoutDivisor;
}
void DirectSubmissionController::updateLastSubmittedThrottle(QueueThrottle throttle) {
if (throttle < this->lowestThrottleSubmitted) {
this->lowestThrottleSubmitted = throttle;
}
}
size_t DirectSubmissionController::getTimeoutParamsMapKey(QueueThrottle throttle, bool acLineStatus) {
return (static_cast<size_t>(throttle) << 1) + acLineStatus;
}
void DirectSubmissionController::unregisterDirectSubmission(CommandStreamReceiver *csr) {
std::lock_guard<std::mutex> lock(directSubmissionsMutex);
directSubmissions.erase(csr);
@@ -78,8 +110,9 @@ void *DirectSubmissionController::controlDirectSubmissionsState(void *self) {
void DirectSubmissionController::checkNewSubmissions() {
std::lock_guard<std::mutex> lock(this->directSubmissionsMutex);
bool shouldRecalculateTimeout = false;
CommandStreamReceiver *csr = nullptr;
for (auto &directSubmission : this->directSubmissions) {
auto csr = directSubmission.first;
csr = directSubmission.first;
auto &state = directSubmission.second;
auto taskCount = csr->peekTaskCount();
@@ -91,10 +124,15 @@ void DirectSubmissionController::checkNewSubmissions() {
csr->stopDirectSubmission(false);
state.isStopped = true;
shouldRecalculateTimeout = true;
this->lowestThrottleSubmitted = QueueThrottle::HIGH;
}
} else {
state.isStopped = false;
state.taskCount = taskCount;
if (this->adjustTimeoutOnThrottleAndAcLineStatus) {
this->updateLastSubmittedThrottle(csr->getLastDirectSubmissionThrottle());
this->applyTimeoutForAcLineStatusAndThrottle(csr->getAcLineConnected(true));
}
}
}
if (shouldRecalculateTimeout) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2019-2023 Intel Corporation
* Copyright (C) 2019-2024 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -7,6 +7,7 @@
#pragma once
#include "shared/source/command_stream/queue_throttle.h"
#include "shared/source/command_stream/task_count_helper.h"
#include "shared/source/helpers/device_bitfield.h"
@@ -21,15 +22,24 @@ namespace NEO {
class MemoryManager;
class CommandStreamReceiver;
class Thread;
class ProductHelper;
using SteadyClock = std::chrono::steady_clock;
struct TimeoutParams {
std::chrono::microseconds maxTimeout;
std::chrono::microseconds timeout;
int timeoutDivisor;
bool directSubmissionEnabled;
};
class DirectSubmissionController {
public:
static constexpr size_t defaultTimeout = 5'000;
DirectSubmissionController();
virtual ~DirectSubmissionController();
void setTimeoutParamsForPlatform(const ProductHelper &helper);
void registerDirectSubmission(CommandStreamReceiver *csr);
void unregisterDirectSubmission(CommandStreamReceiver *csr);
@@ -50,6 +60,9 @@ class DirectSubmissionController {
void adjustTimeout(CommandStreamReceiver *csr);
void recalculateTimeout();
void applyTimeoutForAcLineStatusAndThrottle(bool acLineConnected);
void updateLastSubmittedThrottle(QueueThrottle throttle);
size_t getTimeoutParamsMapKey(QueueThrottle throttle, bool acLineStatus);
uint32_t maxCcsCount = 1u;
std::array<uint32_t, DeviceBitfield().size()> ccsCount = {};
@@ -64,5 +77,8 @@ class DirectSubmissionController {
std::chrono::microseconds maxTimeout{defaultTimeout};
std::chrono::microseconds timeout{defaultTimeout};
int timeoutDivisor = 1;
std::unordered_map<size_t, TimeoutParams> timeoutParamsMap;
QueueThrottle lowestThrottleSubmitted = QueueThrottle::HIGH;
bool adjustTimeoutOnThrottleAndAcLineStatus = true;
};
} // namespace NEO

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Intel Corporation
* Copyright (C) 2020-2024 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -95,6 +95,10 @@ class DirectSubmissionHw {
virtual void flushMonitorFence(){};
QueueThrottle getLastSubmittedThrottle() {
return this->lastSubmittedThrottle;
}
protected:
static constexpr size_t prefetchSize = 8 * MemoryConstants::cacheLineSize;
static constexpr size_t prefetchNoops = prefetchSize / sizeof(uint32_t);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2023 Intel Corporation
* Copyright (C) 2018-2024 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -53,6 +53,7 @@ class KmdNotifyHelper {
bool quickKmdSleepForSporadicWaitsEnabled() const { return properties->enableQuickKmdSleepForSporadicWaits; }
MOCKABLE_VIRTUAL void updateLastWaitForCompletionTimestamp();
MOCKABLE_VIRTUAL void updateAcLineStatus();
bool getAcLineConnected() const { return acLineConnected.load(); }
static void overrideFromDebugVariable(int32_t debugVariableValue, int64_t &destination);
static void overrideFromDebugVariable(int32_t debugVariableValue, bool &destination);

View File

@@ -6,6 +6,7 @@
*/
#pragma once
#include "shared/source/command_stream/queue_throttle.h"
#include "shared/source/command_stream/task_count_helper.h"
#include "aubstream/engine_node.h"
@@ -39,6 +40,7 @@ class ReleaseHelper;
class GraphicsAllocation;
class MemoryManager;
struct RootDeviceEnvironment;
struct TimeoutParams;
class OSInterface;
class DriverModel;
enum class DriverModelType;
@@ -112,6 +114,7 @@ class ProductHelper {
virtual bool isNewResidencyModelSupported() const = 0;
virtual bool isDirectSubmissionSupported(ReleaseHelper *releaseHelper) const = 0;
virtual bool isDirectSubmissionConstantCacheInvalidationNeeded(const HardwareInfo &hwInfo) const = 0;
virtual TimeoutParams getDirectSubmissionControllerTimeoutParams(bool acLineConnected, QueueThrottle queueThrottle) const = 0;
virtual std::pair<bool, bool> isPipeControlPriorToNonPipelinedStateCommandsWARequired(const HardwareInfo &hwInfo, bool isRcs, const ReleaseHelper *releaseHelper) const = 0;
virtual bool heapInLocalMem(const HardwareInfo &hwInfo) const = 0;
virtual void setCapabilityCoherencyFlag(const HardwareInfo &hwInfo, bool &coherencyFlag) = 0;

View File

@@ -8,6 +8,7 @@
#include "shared/source/aub_mem_dump/aub_mem_dump.h"
#include "shared/source/command_stream/stream_properties.h"
#include "shared/source/debug_settings/debug_settings_manager.h"
#include "shared/source/direct_submission/direct_submission_controller.h"
#include "shared/source/execution_environment/root_device_environment.h"
#include "shared/source/helpers/cache_policy.h"
#include "shared/source/helpers/constants.h"
@@ -356,6 +357,16 @@ bool ProductHelperHw<gfxProduct>::isDirectSubmissionConstantCacheInvalidationNee
return false;
}
template <PRODUCT_FAMILY gfxProduct>
TimeoutParams ProductHelperHw<gfxProduct>::getDirectSubmissionControllerTimeoutParams(bool acLineConnected, QueueThrottle queueThrottle) const {
TimeoutParams params{};
params.maxTimeout = std::chrono::microseconds{DirectSubmissionController::defaultTimeout};
params.timeout = std::chrono::microseconds{DirectSubmissionController::defaultTimeout};
params.timeoutDivisor = 1;
params.directSubmissionEnabled = true;
return params;
}
template <PRODUCT_FAMILY gfxProduct>
bool ProductHelperHw<gfxProduct>::isForceEmuInt32DivRemSPWARequired(const HardwareInfo &hwInfo) const {
return false;

View File

@@ -59,6 +59,7 @@ class ProductHelperHw : public ProductHelper {
bool isNewResidencyModelSupported() const override;
bool isDirectSubmissionSupported(ReleaseHelper *releaseHelper) const override;
bool isDirectSubmissionConstantCacheInvalidationNeeded(const HardwareInfo &hwInfo) const override;
TimeoutParams getDirectSubmissionControllerTimeoutParams(bool acLineConnected, QueueThrottle queueThrottle) const override;
std::pair<bool, bool> isPipeControlPriorToNonPipelinedStateCommandsWARequired(const HardwareInfo &hwInfo, bool isRcs, const ReleaseHelper *releaseHelper) const override;
bool heapInLocalMem(const HardwareInfo &hwInfo) const override;
void setCapabilityCoherencyFlag(const HardwareInfo &hwInfo, bool &coherencyFlag) override;

View File

@@ -66,6 +66,7 @@ set(NEO_CORE_tests_mocks
${CMAKE_CURRENT_SOURCE_DIR}/mock_graphics_allocation.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_host_ptr_manager.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_gfx_core_helper.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_kmd_notify_helper.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_product_helper.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mock_release_helper.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_internal_allocation_storage.h

View File

@@ -219,6 +219,14 @@ class MockCommandStreamReceiver : public CommandStreamReceiver {
}
SubmissionStatus initializeDeviceWithFirstSubmission(Device &device) override { return SubmissionStatus::success; }
QueueThrottle getLastDirectSubmissionThrottle() override {
return getLastDirectSubmissionThrottleReturnValue;
}
bool getAcLineConnected(bool updateStatus) const override {
return getAcLineConnectedReturnValue;
}
static constexpr size_t tagSize = 256;
static volatile TagAddressType mockTagAddress[tagSize];
std::vector<char> instructionHeapReserveredData;
@@ -242,6 +250,8 @@ class MockCommandStreamReceiver : public CommandStreamReceiver {
WaitStatus waitForCompletionWithTimeoutReturnValue{WaitStatus::ready};
CommandStreamReceiverType commandStreamReceiverType = CommandStreamReceiverType::CSR_HW;
BatchBuffer latestFlushedBatchBuffer = {};
QueueThrottle getLastDirectSubmissionThrottleReturnValue = QueueThrottle::MEDIUM;
bool getAcLineConnectedReturnValue = true;
};
class MockCommandStreamReceiverWithFailingSubmitBatch : public MockCommandStreamReceiver {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Intel Corporation
* Copyright (C) 2020-2024 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -58,6 +58,7 @@ struct MockDirectSubmissionHw : public DirectSubmissionHw<GfxFamily, Dispatcher>
using BaseClass::immWritePostSyncOffset;
using BaseClass::inputMonitorFenceDispatchRequirement;
using BaseClass::isDisablePrefetcherRequired;
using BaseClass::lastSubmittedThrottle;
using BaseClass::miMemFenceRequired;
using BaseClass::osContext;
using BaseClass::partitionConfigSet;

View File

@@ -0,0 +1,36 @@
/*
* Copyright (C) 2024 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/helpers/kmd_notify_properties.h"
namespace NEO {
class MockKmdNotifyHelper : public KmdNotifyHelper {
public:
using KmdNotifyHelper::acLineConnected;
using KmdNotifyHelper::getMicrosecondsSinceEpoch;
using KmdNotifyHelper::lastWaitForCompletionTimestampUs;
using KmdNotifyHelper::properties;
MockKmdNotifyHelper() = delete;
MockKmdNotifyHelper(const KmdNotifyProperties *newProperties) : KmdNotifyHelper(newProperties){};
void updateLastWaitForCompletionTimestamp() override {
KmdNotifyHelper::updateLastWaitForCompletionTimestamp();
updateLastWaitForCompletionTimestampCalled++;
}
void updateAcLineStatus() override {
KmdNotifyHelper::updateAcLineStatus();
updateAcLineStatusCalled++;
}
uint32_t updateLastWaitForCompletionTimestampCalled = 0u;
uint32_t updateAcLineStatusCalled = 0u;
};
} // namespace NEO

View File

@@ -596,4 +596,5 @@ PrintMmapAndMunMapCalls = -1
UseLocalPreferredForCacheableBuffers = -1
EnableFtrTile64Optimization = -1
ForceTlbFlushWithTaskCountAfterCopy = -1
DirectSubmissionControllerAdjustOnThrottleAndAcLineStatus = -1
# Please don't edit below this line

View File

@@ -43,6 +43,7 @@
#include "shared/test/common/mocks/mock_driver_model.h"
#include "shared/test/common/mocks/mock_execution_environment.h"
#include "shared/test/common/mocks/mock_internal_allocation_storage.h"
#include "shared/test/common/mocks/mock_kmd_notify_helper.h"
#include "shared/test/common/mocks/mock_memory_manager.h"
#include "shared/test/common/mocks/mock_os_context.h"
#include "shared/test/common/mocks/mock_scratch_space_controller_xehp_and_later.h"
@@ -5045,6 +5046,26 @@ HWTEST_F(CommandStreamReceiverHwTest, givenForcePipeControlPriorToWalkerWhenAddP
EXPECT_TRUE(pc->getCommandStreamerStallEnable());
}
HWTEST_F(CommandStreamReceiverTest, givenCsrWhenGetAcLineConnectedCalledThenCorrectValueIsReturned) {
auto &csr = pDevice->getUltCommandStreamReceiver<FamilyType>();
auto mockKmdNotifyHelper = new MockKmdNotifyHelper(&pDevice->getHardwareInfo().capabilityTable.kmdNotifyProperties);
csr.resetKmdNotifyHelper(mockKmdNotifyHelper);
EXPECT_EQ(1u, mockKmdNotifyHelper->updateAcLineStatusCalled);
csr.getAcLineConnected(false);
EXPECT_EQ(1u, mockKmdNotifyHelper->updateAcLineStatusCalled);
csr.getAcLineConnected(true);
EXPECT_EQ(2u, mockKmdNotifyHelper->updateAcLineStatusCalled);
mockKmdNotifyHelper->acLineConnected.store(false);
EXPECT_FALSE(csr.getAcLineConnected(false));
mockKmdNotifyHelper->acLineConnected.store(true);
EXPECT_TRUE(csr.getAcLineConnected(false));
}
HWTEST_F(CommandStreamReceiverTest, givenBcsCsrWhenInitializeDeviceWithFirstSubmissionIsCalledThenSuccessIsReturned) {
MockOsContext mockOsContext(0, EngineDescriptorHelper::getDefaultDescriptor({aub_stream::EngineType::ENGINE_BCS, EngineUsage::regular}));
MockCsrHw<FamilyType> commandStreamReceiver(*pDevice->executionEnvironment, pDevice->getRootDeviceIndex(), pDevice->getDeviceBitfield());

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2019-2023 Intel Corporation
* Copyright (C) 2019-2024 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -11,15 +11,19 @@
namespace NEO {
struct DirectSubmissionControllerMock : public DirectSubmissionController {
using DirectSubmissionController::adjustTimeoutOnThrottleAndAcLineStatus;
using DirectSubmissionController::checkNewSubmissions;
using DirectSubmissionController::directSubmissionControllingThread;
using DirectSubmissionController::directSubmissions;
using DirectSubmissionController::directSubmissionsMutex;
using DirectSubmissionController::getTimeoutParamsMapKey;
using DirectSubmissionController::keepControlling;
using DirectSubmissionController::lastTerminateCpuTimestamp;
using DirectSubmissionController::lowestThrottleSubmitted;
using DirectSubmissionController::maxTimeout;
using DirectSubmissionController::timeout;
using DirectSubmissionController::timeoutDivisor;
using DirectSubmissionController::timeoutParamsMap;
void sleep() override {
DirectSubmissionController::sleep();

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2019-2023 Intel Corporation
* Copyright (C) 2019-2024 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -128,6 +128,7 @@ TEST(DirectSubmissionControllerTests, givenDirectSubmissionControllerAndDivisorD
DebugManagerStateRestore restorer;
debugManager.flags.DirectSubmissionControllerMaxTimeout.set(200'000);
debugManager.flags.DirectSubmissionControllerDivisor.set(1);
debugManager.flags.DirectSubmissionControllerAdjustOnThrottleAndAcLineStatus.set(0);
MockExecutionEnvironment executionEnvironment;
executionEnvironment.prepareRootDeviceEnvironments(1);
executionEnvironment.initializeMemoryManager();
@@ -205,6 +206,140 @@ TEST(DirectSubmissionControllerTests, givenDirectSubmissionControllerAndDivisorD
controller.unregisterDirectSubmission(&csr);
}
void fillTimeoutParamsMap(DirectSubmissionControllerMock &controller) {
controller.timeoutParamsMap.clear();
for (auto throttle : {QueueThrottle::LOW, QueueThrottle::MEDIUM, QueueThrottle::HIGH}) {
for (auto acLineStatus : {false, true}) {
auto key = controller.getTimeoutParamsMapKey(throttle, acLineStatus);
TimeoutParams params{};
params.maxTimeout = std::chrono::microseconds{500u + static_cast<size_t>(throttle) * 500u + (acLineStatus ? 0u : 1500u)};
params.timeout = params.maxTimeout;
params.timeoutDivisor = 1;
params.directSubmissionEnabled = true;
auto keyValue = std::make_pair(key, params);
bool result = false;
std::tie(std::ignore, result) = controller.timeoutParamsMap.insert(keyValue);
EXPECT_TRUE(result);
}
}
}
TEST(DirectSubmissionControllerTests, givenDirectSubmissionControllerAndAdjustOnThrottleAndAcLineStatusEnabledWhenThrottleOrAcLineStatusChangesThenTimeoutIsChanged) {
DebugManagerStateRestore restorer;
debugManager.flags.DirectSubmissionControllerDivisor.set(1);
debugManager.flags.DirectSubmissionControllerAdjustOnThrottleAndAcLineStatus.set(1);
MockExecutionEnvironment executionEnvironment;
executionEnvironment.prepareRootDeviceEnvironments(1);
executionEnvironment.initializeMemoryManager();
DeviceBitfield deviceBitfield(1);
MockCommandStreamReceiver csr(executionEnvironment, 0, deviceBitfield);
std::unique_ptr<OsContext> osContext(OsContext::create(nullptr, 0, 0,
EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_CCS, EngineUsage::regular},
PreemptionMode::ThreadGroup, deviceBitfield)));
csr.setupContext(*osContext.get());
DirectSubmissionControllerMock controller;
controller.keepControlling.store(false);
controller.directSubmissionControllingThread->join();
controller.directSubmissionControllingThread.reset();
controller.registerDirectSubmission(&csr);
EXPECT_TRUE(controller.adjustTimeoutOnThrottleAndAcLineStatus);
fillTimeoutParamsMap(controller);
{
controller.lowestThrottleSubmitted = QueueThrottle::HIGH;
csr.getLastDirectSubmissionThrottleReturnValue = QueueThrottle::LOW;
csr.getAcLineConnectedReturnValue = true;
csr.taskCount.store(1u);
controller.checkNewSubmissions();
EXPECT_FALSE(controller.directSubmissions[&csr].isStopped);
EXPECT_EQ(controller.directSubmissions[&csr].taskCount, 1u);
EXPECT_EQ(std::chrono::microseconds{500u}, controller.timeout);
EXPECT_EQ(std::chrono::microseconds{500u}, controller.maxTimeout);
EXPECT_EQ(1, controller.timeoutDivisor);
}
{
controller.lowestThrottleSubmitted = QueueThrottle::HIGH;
csr.getLastDirectSubmissionThrottleReturnValue = QueueThrottle::MEDIUM;
csr.getAcLineConnectedReturnValue = true;
csr.taskCount.store(2u);
controller.checkNewSubmissions();
EXPECT_FALSE(controller.directSubmissions[&csr].isStopped);
EXPECT_EQ(controller.directSubmissions[&csr].taskCount, 2u);
EXPECT_EQ(std::chrono::microseconds{1000u}, controller.timeout);
EXPECT_EQ(std::chrono::microseconds{1000u}, controller.maxTimeout);
EXPECT_EQ(1, controller.timeoutDivisor);
}
{
controller.lowestThrottleSubmitted = QueueThrottle::HIGH;
csr.getLastDirectSubmissionThrottleReturnValue = QueueThrottle::HIGH;
csr.getAcLineConnectedReturnValue = true;
csr.taskCount.store(3u);
controller.checkNewSubmissions();
EXPECT_FALSE(controller.directSubmissions[&csr].isStopped);
EXPECT_EQ(controller.directSubmissions[&csr].taskCount, 3u);
EXPECT_EQ(std::chrono::microseconds{1500u}, controller.timeout);
EXPECT_EQ(std::chrono::microseconds{1500u}, controller.maxTimeout);
EXPECT_EQ(1, controller.timeoutDivisor);
}
{
controller.lowestThrottleSubmitted = QueueThrottle::HIGH;
csr.getLastDirectSubmissionThrottleReturnValue = QueueThrottle::LOW;
csr.getAcLineConnectedReturnValue = false;
csr.taskCount.store(4u);
controller.checkNewSubmissions();
EXPECT_FALSE(controller.directSubmissions[&csr].isStopped);
EXPECT_EQ(controller.directSubmissions[&csr].taskCount, 4u);
EXPECT_EQ(std::chrono::microseconds{2000u}, controller.timeout);
EXPECT_EQ(std::chrono::microseconds{2000u}, controller.maxTimeout);
EXPECT_EQ(1, controller.timeoutDivisor);
}
{
controller.lowestThrottleSubmitted = QueueThrottle::HIGH;
csr.getLastDirectSubmissionThrottleReturnValue = QueueThrottle::MEDIUM;
csr.getAcLineConnectedReturnValue = false;
csr.taskCount.store(5u);
controller.checkNewSubmissions();
EXPECT_FALSE(controller.directSubmissions[&csr].isStopped);
EXPECT_EQ(controller.directSubmissions[&csr].taskCount, 5u);
EXPECT_EQ(std::chrono::microseconds{2500u}, controller.timeout);
EXPECT_EQ(std::chrono::microseconds{2500u}, controller.maxTimeout);
EXPECT_EQ(1, controller.timeoutDivisor);
}
{
controller.lowestThrottleSubmitted = QueueThrottle::HIGH;
csr.getLastDirectSubmissionThrottleReturnValue = QueueThrottle::HIGH;
csr.getAcLineConnectedReturnValue = false;
csr.taskCount.store(6u);
controller.checkNewSubmissions();
EXPECT_FALSE(controller.directSubmissions[&csr].isStopped);
EXPECT_EQ(controller.directSubmissions[&csr].taskCount, 6u);
EXPECT_EQ(std::chrono::microseconds{3000u}, controller.timeout);
EXPECT_EQ(std::chrono::microseconds{3000u}, controller.maxTimeout);
EXPECT_EQ(1, controller.timeoutDivisor);
}
{
controller.lowestThrottleSubmitted = QueueThrottle::LOW;
controller.checkNewSubmissions();
EXPECT_EQ(QueueThrottle::HIGH, controller.lowestThrottleSubmitted);
}
controller.unregisterDirectSubmission(&csr);
}
TEST(DirectSubmissionControllerTests, givenDirectSubmissionControllerWithNotStartedControllingWhenShuttingDownThenNoHang) {
DirectSubmissionControllerMock controller;
EXPECT_NE(controller.directSubmissionControllingThread.get(), nullptr);

View File

@@ -161,6 +161,48 @@ HWTEST_F(DirectSubmissionTest, givenDeviceStopDirectSubmissionAndWaitForCompleti
csr.blitterDirectSubmission.release();
}
HWTEST_F(DirectSubmissionTest, givenCsrWhenGetLastDirectSubmissionThrottleCalledThenDirectSubmissionLastSubmittedThrottleReturned) {
VariableBackup<UltHwConfig> backup(&ultHwConfig);
ultHwConfig.csrBaseCallDirectSubmissionAvailable = false;
ultHwConfig.csrBaseCallBlitterDirectSubmissionAvailable = false;
MockDirectSubmissionHw<FamilyType, RenderDispatcher<FamilyType>> directSubmission(*pDevice->getDefaultEngine().commandStreamReceiver);
auto &csr = pDevice->getUltCommandStreamReceiver<FamilyType>();
csr.directSubmission.reset(&directSubmission);
csr.directSubmissionAvailable = true;
directSubmission.lastSubmittedThrottle = QueueThrottle::LOW;
EXPECT_EQ(QueueThrottle::LOW, csr.getLastDirectSubmissionThrottle());
csr.directSubmissionAvailable = false;
EXPECT_EQ(QueueThrottle::MEDIUM, csr.getLastDirectSubmissionThrottle());
csr.directSubmission.release();
}
HWTEST_F(DirectSubmissionTest, givenBcsCsrWhenGetLastDirectSubmissionThrottleCalledThenDirectSubmissionLastSubmittedThrottleReturned) {
VariableBackup<UltHwConfig> backup(&ultHwConfig);
ultHwConfig.csrBaseCallDirectSubmissionAvailable = false;
ultHwConfig.csrBaseCallBlitterDirectSubmissionAvailable = false;
MockDirectSubmissionHw<FamilyType, BlitterDispatcher<FamilyType>> directSubmission(*pDevice->getDefaultEngine().commandStreamReceiver);
auto &csr = pDevice->getUltCommandStreamReceiver<FamilyType>();
std::unique_ptr<OsContext> osContext(OsContext::create(pDevice->getExecutionEnvironment()->rootDeviceEnvironments[0]->osInterface.get(), pDevice->getRootDeviceIndex(), 0,
EngineDescriptorHelper::getDefaultDescriptor({aub_stream::ENGINE_BCS, EngineUsage::regular},
PreemptionMode::ThreadGroup, pDevice->getDeviceBitfield())));
csr.blitterDirectSubmission.reset(&directSubmission);
csr.setupContext(*osContext);
csr.blitterDirectSubmissionAvailable = true;
directSubmission.lastSubmittedThrottle = QueueThrottle::LOW;
EXPECT_EQ(QueueThrottle::LOW, csr.getLastDirectSubmissionThrottle());
csr.blitterDirectSubmissionAvailable = false;
EXPECT_EQ(QueueThrottle::MEDIUM, csr.getLastDirectSubmissionThrottle());
csr.blitterDirectSubmission.release();
}
HWTEST_F(DirectSubmissionTest, givenDirectSubmissionStopRingBufferBlockingCalledAndRingBufferIsNotStartedThenEnsureRingCompletionCalled) {
MockDirectSubmissionHw<FamilyType, RenderDispatcher<FamilyType>> directSubmission(*pDevice->getDefaultEngine().commandStreamReceiver);
bool ret = directSubmission.initialize(false, false);