Optimize power usage in VA sharing scenarios.
- in VA sharing scenarios driver needs to be as power efficient as possible - Added new mode to KMD notify helper called maxPowerSavingMode - in this mode, whenever GPU is not busy, driver will choose non busy wait path. Change-Id: I7e4079be995107bea543ffda774ca161ce483944
This commit is contained in:
parent
b4b4a306d4
commit
d53e1c3979
|
@ -144,6 +144,10 @@ class CommandStreamReceiver {
|
||||||
|
|
||||||
bool initializeTagAllocation();
|
bool initializeTagAllocation();
|
||||||
|
|
||||||
|
KmdNotifyHelper *peekKmdNotifyHelper() {
|
||||||
|
return kmdNotifyHelper.get();
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setDisableL3Cache(bool val) {
|
void setDisableL3Cache(bool val) {
|
||||||
disableL3Cache = val;
|
disableL3Cache = val;
|
||||||
|
@ -195,6 +199,7 @@ class CommandStreamReceiver {
|
||||||
IndirectHeap *indirectHeap[IndirectHeap::NUM_TYPES];
|
IndirectHeap *indirectHeap[IndirectHeap::NUM_TYPES];
|
||||||
std::unique_ptr<FlatBatchBufferHelper> flatBatchBufferHelper;
|
std::unique_ptr<FlatBatchBufferHelper> flatBatchBufferHelper;
|
||||||
std::unique_ptr<ExperimentalCommandBuffer> experimentalCmdBuffer;
|
std::unique_ptr<ExperimentalCommandBuffer> experimentalCmdBuffer;
|
||||||
|
std::unique_ptr<KmdNotifyHelper> kmdNotifyHelper;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef CommandStreamReceiver *(*CommandStreamReceiverCreateFunc)(const HardwareInfo &hwInfoIn, bool withAubDump);
|
typedef CommandStreamReceiver *(*CommandStreamReceiverCreateFunc)(const HardwareInfo &hwInfoIn, bool withAubDump);
|
||||||
|
|
|
@ -109,8 +109,6 @@ class CommandStreamReceiverHw : public CommandStreamReceiver {
|
||||||
|
|
||||||
const HardwareInfo &hwInfo;
|
const HardwareInfo &hwInfo;
|
||||||
CsrSizeRequestFlags csrSizeRequestFlags = {};
|
CsrSizeRequestFlags csrSizeRequestFlags = {};
|
||||||
|
|
||||||
std::unique_ptr<KmdNotifyHelper> kmdNotifyHelper;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace OCLRT
|
} // namespace OCLRT
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "runtime/platform/platform.h"
|
#include "runtime/platform/platform.h"
|
||||||
#include "runtime/helpers/string.h"
|
#include "runtime/helpers/string.h"
|
||||||
#include "runtime/command_queue/command_queue.h"
|
#include "runtime/command_queue/command_queue.h"
|
||||||
|
#include "runtime/command_stream/command_stream_receiver.h"
|
||||||
#include "runtime/built_ins/built_ins.h"
|
#include "runtime/built_ins/built_ins.h"
|
||||||
#include "runtime/compiler_interface/compiler_interface.h"
|
#include "runtime/compiler_interface/compiler_interface.h"
|
||||||
#include "runtime/memory_manager/svm_memory_manager.h"
|
#include "runtime/memory_manager/svm_memory_manager.h"
|
||||||
|
@ -174,11 +175,15 @@ bool Context::createImpl(const cl_context_properties *properties,
|
||||||
|
|
||||||
// We currently assume each device uses the same MemoryManager
|
// We currently assume each device uses the same MemoryManager
|
||||||
if (devices.size() > 0) {
|
if (devices.size() > 0) {
|
||||||
this->memoryManager = this->getDevice(0)->getMemoryManager();
|
auto device = this->getDevice(0);
|
||||||
|
this->memoryManager = device->getMemoryManager();
|
||||||
this->svmAllocsManager = new SVMAllocsManager(this->memoryManager);
|
this->svmAllocsManager = new SVMAllocsManager(this->memoryManager);
|
||||||
if (memoryManager->isAsyncDeleterEnabled()) {
|
if (memoryManager->isAsyncDeleterEnabled()) {
|
||||||
memoryManager->getDeferredDeleter()->addClient();
|
memoryManager->getDeferredDeleter()->addClient();
|
||||||
}
|
}
|
||||||
|
if (sharingBuilder->isSharingPresent(SharingType::VA_SHARING)) {
|
||||||
|
device->getCommandStreamReceiver().peekKmdNotifyHelper()->initMaxPowerSavingMode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &device : devices) {
|
for (auto &device : devices) {
|
||||||
|
|
|
@ -37,7 +37,9 @@ bool KmdNotifyHelper::obtainTimeoutParams(int64_t &timeoutValueOutput,
|
||||||
|
|
||||||
quickKmdSleepRequest |= applyQuickKmdSleepForSporadicWait();
|
quickKmdSleepRequest |= applyQuickKmdSleepForSporadicWait();
|
||||||
|
|
||||||
if (!properties->enableKmdNotify && !acLineConnected) {
|
if (maxPowerSavingMode) {
|
||||||
|
timeoutValueOutput = 1;
|
||||||
|
} else if (!properties->enableKmdNotify && !acLineConnected) {
|
||||||
timeoutValueOutput = KmdNotifyConstants::timeoutInMicrosecondsForDisconnectedAcLine;
|
timeoutValueOutput = KmdNotifyConstants::timeoutInMicrosecondsForDisconnectedAcLine;
|
||||||
} else if (quickKmdSleepRequest && properties->enableQuickKmdSleep) {
|
} else if (quickKmdSleepRequest && properties->enableQuickKmdSleep) {
|
||||||
timeoutValueOutput = properties->delayQuickKmdSleepMicroseconds;
|
timeoutValueOutput = properties->delayQuickKmdSleepMicroseconds;
|
||||||
|
|
|
@ -64,6 +64,10 @@ class KmdNotifyHelper {
|
||||||
static void overrideFromDebugVariable(int32_t debugVariableValue, int64_t &destination);
|
static void overrideFromDebugVariable(int32_t debugVariableValue, int64_t &destination);
|
||||||
static void overrideFromDebugVariable(int32_t debugVariableValue, bool &destination);
|
static void overrideFromDebugVariable(int32_t debugVariableValue, bool &destination);
|
||||||
|
|
||||||
|
void initMaxPowerSavingMode() {
|
||||||
|
maxPowerSavingMode = true;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool applyQuickKmdSleepForSporadicWait() const;
|
bool applyQuickKmdSleepForSporadicWait() const;
|
||||||
int64_t getBaseTimeout(const int64_t &multiplier) const;
|
int64_t getBaseTimeout(const int64_t &multiplier) const;
|
||||||
|
@ -72,5 +76,6 @@ class KmdNotifyHelper {
|
||||||
const KmdNotifyProperties *properties = nullptr;
|
const KmdNotifyProperties *properties = nullptr;
|
||||||
std::atomic<int64_t> lastWaitForCompletionTimestampUs{0};
|
std::atomic<int64_t> lastWaitForCompletionTimestampUs{0};
|
||||||
std::atomic<bool> acLineConnected{true};
|
std::atomic<bool> acLineConnected{true};
|
||||||
|
bool maxPowerSavingMode = false;
|
||||||
};
|
};
|
||||||
} // namespace OCLRT
|
} // namespace OCLRT
|
||||||
|
|
|
@ -81,6 +81,10 @@ bool SharingFactory::finalizeProperties(Context &context, int32_t &errcodeRet) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SharingFactory::isSharingPresent(SharingType sharingId) {
|
||||||
|
return sharingContextBuilder[sharingId] != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
SharingBuilderFactory *SharingFactory::sharingContextBuilder[SharingType::MAX_SHARING_VALUE] = {
|
SharingBuilderFactory *SharingFactory::sharingContextBuilder[SharingType::MAX_SHARING_VALUE] = {
|
||||||
nullptr,
|
nullptr,
|
||||||
};
|
};
|
||||||
|
|
|
@ -70,6 +70,7 @@ class SharingFactory {
|
||||||
static std::unique_ptr<SharingFactory> build();
|
static std::unique_ptr<SharingFactory> build();
|
||||||
bool processProperties(cl_context_properties &propertyType, cl_context_properties &propertyValue, cl_int &errcodeRet);
|
bool processProperties(cl_context_properties &propertyType, cl_context_properties &propertyValue, cl_int &errcodeRet);
|
||||||
bool finalizeProperties(Context &context, int32_t &errcodeRet);
|
bool finalizeProperties(Context &context, int32_t &errcodeRet);
|
||||||
|
bool isSharingPresent(SharingType sharingId);
|
||||||
std::string getExtensions();
|
std::string getExtensions();
|
||||||
void fillGlobalDispatchTable();
|
void fillGlobalDispatchTable();
|
||||||
void *getExtensionFunctionAddress(const std::string &functionName);
|
void *getExtensionFunctionAddress(const std::string &functionName);
|
||||||
|
|
|
@ -59,6 +59,7 @@ struct KmdNotifyTests : public ::testing::Test {
|
||||||
using KmdNotifyHelper::acLineConnected;
|
using KmdNotifyHelper::acLineConnected;
|
||||||
using KmdNotifyHelper::getMicrosecondsSinceEpoch;
|
using KmdNotifyHelper::getMicrosecondsSinceEpoch;
|
||||||
using KmdNotifyHelper::lastWaitForCompletionTimestampUs;
|
using KmdNotifyHelper::lastWaitForCompletionTimestampUs;
|
||||||
|
using KmdNotifyHelper::maxPowerSavingMode;
|
||||||
using KmdNotifyHelper::properties;
|
using KmdNotifyHelper::properties;
|
||||||
|
|
||||||
MockKmdNotifyHelper() = delete;
|
MockKmdNotifyHelper() = delete;
|
||||||
|
@ -334,6 +335,25 @@ TEST_F(KmdNotifyTests, givenDisabledKmdNotifyMechanismWhenAcLineIsDisconnectedTh
|
||||||
EXPECT_EQ(10000, KmdNotifyConstants::timeoutInMicrosecondsForDisconnectedAcLine);
|
EXPECT_EQ(10000, KmdNotifyConstants::timeoutInMicrosecondsForDisconnectedAcLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(KmdNotifyTests, givenKmdNotifyEnabledWhenInitMaxPowerSavingModeIsCalledThenObtainReturnOneAsWaitValue) {
|
||||||
|
localHwInfo.capabilityTable.kmdNotifyProperties.enableKmdNotify = true;
|
||||||
|
MockKmdNotifyHelper helper(&(localHwInfo.capabilityTable.kmdNotifyProperties));
|
||||||
|
|
||||||
|
EXPECT_FALSE(helper.maxPowerSavingMode);
|
||||||
|
|
||||||
|
int64_t timeout = 0;
|
||||||
|
bool timeoutEnabled = helper.obtainTimeoutParams(timeout, false, 1, 2, 2);
|
||||||
|
EXPECT_TRUE(timeoutEnabled);
|
||||||
|
EXPECT_EQ(2, timeout);
|
||||||
|
|
||||||
|
helper.initMaxPowerSavingMode();
|
||||||
|
EXPECT_TRUE(helper.maxPowerSavingMode);
|
||||||
|
timeoutEnabled = helper.obtainTimeoutParams(timeout, false, 1, 2, 2);
|
||||||
|
EXPECT_TRUE(timeoutEnabled);
|
||||||
|
|
||||||
|
EXPECT_EQ(1, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(KmdNotifyTests, givenEnabledKmdNotifyMechanismWhenAcLineIsDisconnectedThenDontChangeTimeoutValue) {
|
TEST_F(KmdNotifyTests, givenEnabledKmdNotifyMechanismWhenAcLineIsDisconnectedThenDontChangeTimeoutValue) {
|
||||||
localHwInfo.capabilityTable.kmdNotifyProperties.enableKmdNotify = true;
|
localHwInfo.capabilityTable.kmdNotifyProperties.enableKmdNotify = true;
|
||||||
localHwInfo.capabilityTable.kmdNotifyProperties.delayKmdNotifyMicroseconds = 5;
|
localHwInfo.capabilityTable.kmdNotifyProperties.delayKmdNotifyMicroseconds = 5;
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "runtime/context/context.h"
|
#include "runtime/context/context.h"
|
||||||
|
#include "runtime/command_stream/command_stream_receiver.h"
|
||||||
#include "runtime/device/device.h"
|
#include "runtime/device/device.h"
|
||||||
#include "runtime/helpers/string.h"
|
#include "runtime/helpers/string.h"
|
||||||
#include "runtime/platform/platform.h"
|
#include "runtime/platform/platform.h"
|
||||||
|
@ -196,6 +197,14 @@ TEST(SharingFactoryTests, givenMockFactoryWithSharingWhenAskedThenAddressIsRetur
|
||||||
EXPECT_EQ(reinterpret_cast<void *>(dummyHandler), ptr);
|
EXPECT_EQ(reinterpret_cast<void *>(dummyHandler), ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(SharingFactoryTests, givenSharingFactoryWhenSharingIsRegisteredThenIsSharingPresentReflectsThatStatus) {
|
||||||
|
SharingFactoryStateRestore stateRestore;
|
||||||
|
stateRestore.clearCurrentState();
|
||||||
|
EXPECT_FALSE(stateRestore.isSharingPresent(SharingType::CLGL_SHARING));
|
||||||
|
stateRestore.registerSharing<MockSharingBuilderFactory>(SharingType::CLGL_SHARING);
|
||||||
|
EXPECT_TRUE(stateRestore.isSharingPresent(SharingType::CLGL_SHARING));
|
||||||
|
}
|
||||||
|
|
||||||
TEST(Context, givenMockSharingBuilderWhenContextWithInvalidPropertiesThenContextCreateShouldFail) {
|
TEST(Context, givenMockSharingBuilderWhenContextWithInvalidPropertiesThenContextCreateShouldFail) {
|
||||||
SharingFactoryStateRestore stateRestore;
|
SharingFactoryStateRestore stateRestore;
|
||||||
|
|
||||||
|
@ -226,3 +235,35 @@ TEST(Context, givenMockSharingBuilderWhenContextWithInvalidPropertiesThenContext
|
||||||
context.reset(Context::create<Context>(validProperties, deviceVector, nullptr, nullptr, retVal));
|
context.reset(Context::create<Context>(validProperties, deviceVector, nullptr, nullptr, retVal));
|
||||||
EXPECT_NE(nullptr, context.get());
|
EXPECT_NE(nullptr, context.get());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TEST(Context, GivenVaContextWhenItIsCreatedItInitializesPowerSavingMode) {
|
||||||
|
SharingFactoryStateRestore stateRestore;
|
||||||
|
|
||||||
|
stateRestore.clearCurrentState();
|
||||||
|
stateRestore.registerSharing<MockSharingBuilderFactory>(SharingType::VA_SHARING);
|
||||||
|
|
||||||
|
std::unique_ptr<MockDevice> device(new MockDevice(*platformDevices[0]));
|
||||||
|
cl_device_id clDevice = static_cast<cl_device_id>(device.get());
|
||||||
|
DeviceVector deviceVector((cl_device_id *)&clDevice, 1);
|
||||||
|
cl_int retVal;
|
||||||
|
|
||||||
|
auto pPlatform = OCLRT::platform();
|
||||||
|
cl_platform_id platformId[1];
|
||||||
|
platformId[0] = pPlatform;
|
||||||
|
|
||||||
|
auto &commandStreamReceiver = device->getCommandStreamReceiver();
|
||||||
|
auto kmdNotifyHelper = commandStreamReceiver.peekKmdNotifyHelper();
|
||||||
|
|
||||||
|
int64_t timeout = 0;
|
||||||
|
kmdNotifyHelper->obtainTimeoutParams(timeout, true, 1, 10, 2);
|
||||||
|
EXPECT_NE(1, timeout);
|
||||||
|
|
||||||
|
cl_context_properties validProperties[5] = {CL_CONTEXT_PLATFORM, (cl_context_properties)platformId[0],
|
||||||
|
clContextPropertyMock, mockContextPassFinalize, 0};
|
||||||
|
|
||||||
|
std::unique_ptr<Context> ctx(Context::create<Context>(validProperties, deviceVector, nullptr, nullptr, retVal));
|
||||||
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||||
|
EXPECT_NE(nullptr, ctx);
|
||||||
|
kmdNotifyHelper->obtainTimeoutParams(timeout, true, 1, 10, 2);
|
||||||
|
EXPECT_EQ(1, timeout);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue