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();
|
||||
|
||||
KmdNotifyHelper *peekKmdNotifyHelper() {
|
||||
return kmdNotifyHelper.get();
|
||||
}
|
||||
|
||||
protected:
|
||||
void setDisableL3Cache(bool val) {
|
||||
disableL3Cache = val;
|
||||
|
@ -195,6 +199,7 @@ class CommandStreamReceiver {
|
|||
IndirectHeap *indirectHeap[IndirectHeap::NUM_TYPES];
|
||||
std::unique_ptr<FlatBatchBufferHelper> flatBatchBufferHelper;
|
||||
std::unique_ptr<ExperimentalCommandBuffer> experimentalCmdBuffer;
|
||||
std::unique_ptr<KmdNotifyHelper> kmdNotifyHelper;
|
||||
};
|
||||
|
||||
typedef CommandStreamReceiver *(*CommandStreamReceiverCreateFunc)(const HardwareInfo &hwInfoIn, bool withAubDump);
|
||||
|
|
|
@ -109,8 +109,6 @@ class CommandStreamReceiverHw : public CommandStreamReceiver {
|
|||
|
||||
const HardwareInfo &hwInfo;
|
||||
CsrSizeRequestFlags csrSizeRequestFlags = {};
|
||||
|
||||
std::unique_ptr<KmdNotifyHelper> kmdNotifyHelper;
|
||||
};
|
||||
|
||||
} // namespace OCLRT
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "runtime/platform/platform.h"
|
||||
#include "runtime/helpers/string.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/compiler_interface/compiler_interface.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
|
||||
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);
|
||||
if (memoryManager->isAsyncDeleterEnabled()) {
|
||||
memoryManager->getDeferredDeleter()->addClient();
|
||||
}
|
||||
if (sharingBuilder->isSharingPresent(SharingType::VA_SHARING)) {
|
||||
device->getCommandStreamReceiver().peekKmdNotifyHelper()->initMaxPowerSavingMode();
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &device : devices) {
|
||||
|
|
|
@ -37,7 +37,9 @@ bool KmdNotifyHelper::obtainTimeoutParams(int64_t &timeoutValueOutput,
|
|||
|
||||
quickKmdSleepRequest |= applyQuickKmdSleepForSporadicWait();
|
||||
|
||||
if (!properties->enableKmdNotify && !acLineConnected) {
|
||||
if (maxPowerSavingMode) {
|
||||
timeoutValueOutput = 1;
|
||||
} else if (!properties->enableKmdNotify && !acLineConnected) {
|
||||
timeoutValueOutput = KmdNotifyConstants::timeoutInMicrosecondsForDisconnectedAcLine;
|
||||
} else if (quickKmdSleepRequest && properties->enableQuickKmdSleep) {
|
||||
timeoutValueOutput = properties->delayQuickKmdSleepMicroseconds;
|
||||
|
|
|
@ -64,6 +64,10 @@ class KmdNotifyHelper {
|
|||
static void overrideFromDebugVariable(int32_t debugVariableValue, int64_t &destination);
|
||||
static void overrideFromDebugVariable(int32_t debugVariableValue, bool &destination);
|
||||
|
||||
void initMaxPowerSavingMode() {
|
||||
maxPowerSavingMode = true;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool applyQuickKmdSleepForSporadicWait() const;
|
||||
int64_t getBaseTimeout(const int64_t &multiplier) const;
|
||||
|
@ -72,5 +76,6 @@ class KmdNotifyHelper {
|
|||
const KmdNotifyProperties *properties = nullptr;
|
||||
std::atomic<int64_t> lastWaitForCompletionTimestampUs{0};
|
||||
std::atomic<bool> acLineConnected{true};
|
||||
bool maxPowerSavingMode = false;
|
||||
};
|
||||
} // namespace OCLRT
|
||||
|
|
|
@ -81,6 +81,10 @@ bool SharingFactory::finalizeProperties(Context &context, int32_t &errcodeRet) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool SharingFactory::isSharingPresent(SharingType sharingId) {
|
||||
return sharingContextBuilder[sharingId] != nullptr;
|
||||
}
|
||||
|
||||
SharingBuilderFactory *SharingFactory::sharingContextBuilder[SharingType::MAX_SHARING_VALUE] = {
|
||||
nullptr,
|
||||
};
|
||||
|
|
|
@ -70,6 +70,7 @@ class SharingFactory {
|
|||
static std::unique_ptr<SharingFactory> build();
|
||||
bool processProperties(cl_context_properties &propertyType, cl_context_properties &propertyValue, cl_int &errcodeRet);
|
||||
bool finalizeProperties(Context &context, int32_t &errcodeRet);
|
||||
bool isSharingPresent(SharingType sharingId);
|
||||
std::string getExtensions();
|
||||
void fillGlobalDispatchTable();
|
||||
void *getExtensionFunctionAddress(const std::string &functionName);
|
||||
|
|
|
@ -59,6 +59,7 @@ struct KmdNotifyTests : public ::testing::Test {
|
|||
using KmdNotifyHelper::acLineConnected;
|
||||
using KmdNotifyHelper::getMicrosecondsSinceEpoch;
|
||||
using KmdNotifyHelper::lastWaitForCompletionTimestampUs;
|
||||
using KmdNotifyHelper::maxPowerSavingMode;
|
||||
using KmdNotifyHelper::properties;
|
||||
|
||||
MockKmdNotifyHelper() = delete;
|
||||
|
@ -334,6 +335,25 @@ TEST_F(KmdNotifyTests, givenDisabledKmdNotifyMechanismWhenAcLineIsDisconnectedTh
|
|||
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) {
|
||||
localHwInfo.capabilityTable.kmdNotifyProperties.enableKmdNotify = true;
|
||||
localHwInfo.capabilityTable.kmdNotifyProperties.delayKmdNotifyMicroseconds = 5;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "gtest/gtest.h"
|
||||
#include "runtime/context/context.h"
|
||||
#include "runtime/command_stream/command_stream_receiver.h"
|
||||
#include "runtime/device/device.h"
|
||||
#include "runtime/helpers/string.h"
|
||||
#include "runtime/platform/platform.h"
|
||||
|
@ -196,6 +197,14 @@ TEST(SharingFactoryTests, givenMockFactoryWithSharingWhenAskedThenAddressIsRetur
|
|||
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) {
|
||||
SharingFactoryStateRestore stateRestore;
|
||||
|
||||
|
@ -226,3 +235,35 @@ TEST(Context, givenMockSharingBuilderWhenContextWithInvalidPropertiesThenContext
|
|||
context.reset(Context::create<Context>(validProperties, deviceVector, nullptr, nullptr, retVal));
|
||||
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