performance: Reuse GPU timestamp instead of KMD escape

Resolves: NEO-10615

Signed-off-by: Morek, Szymon <szymon.morek@intel.com>
This commit is contained in:
Morek, Szymon
2024-04-16 08:50:16 +00:00
committed by Compute-Runtime-Automation
parent 15d7a31148
commit 9ca2091725
10 changed files with 190 additions and 14 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2023 Intel Corporation
* Copyright (C) 2018-2024 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -18,15 +18,28 @@ class MockDeviceTimeDrm : public DeviceTimeDrm {
using DeviceTimeDrm::pDrm;
bool getGpuCpuTimeImpl(TimeStampData *pGpuCpuTime, OSTime *osTime) override {
getGpuCpuTimeImplCalled++;
if (callBaseGetGpuCpuTimeImpl) {
return DeviceTimeDrm::getGpuCpuTimeImpl(pGpuCpuTime, osTime);
}
*pGpuCpuTime = gpuCpuTimeValue;
return getGpuCpuTimeImplResult;
}
double getDynamicDeviceTimerResolution(HardwareInfo const &hwInfo) const override {
if (callGetDynamicDeviceTimerResolution) {
return DeviceTimeDrm::getDynamicDeviceTimerResolution(hwInfo);
}
return dynamicDeviceTimerResolutionValue;
}
bool callBaseGetGpuCpuTimeImpl = true;
bool getGpuCpuTimeImplResult = true;
TimeStampData gpuCpuTimeValue{};
uint32_t getGpuCpuTimeImplCalled = 0;
bool callGetDynamicDeviceTimerResolution = false;
double dynamicDeviceTimerResolutionValue = 1.0;
};
class MockOSTimeLinux : public OSTimeLinux {

View File

@@ -50,11 +50,11 @@ const char *MockDevice::getProductAbbrev() const {
MockDevice::MockDevice(ExecutionEnvironment *executionEnvironment, uint32_t rootDeviceIndex)
: RootDevice(executionEnvironment, rootDeviceIndex) {
UltDeviceFactory::initializeMemoryManager(*executionEnvironment);
auto &hwInfo = getHardwareInfo();
if (!getOSTime()) {
getRootDeviceEnvironmentRef().osTime = MockOSTime::create();
getRootDeviceEnvironmentRef().osTime->setDeviceTimerResolution(hwInfo);
}
auto &hwInfo = getHardwareInfo();
executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->setHwInfoAndInitHelpers(&hwInfo);
executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->initGmm();
if (!executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->memoryOperationsInterface) {

View File

@@ -599,4 +599,5 @@ ForceTlbFlushWithTaskCountAfterCopy = -1
ForceSynchronizedDispatchMode = -1
DirectSubmissionControllerAdjustOnThrottleAndAcLineStatus = -1
ReadOnlyAllocationsTypeMask = 0
GpuTimestampRefreshTimeout = -1
# Please don't edit below this line

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/linux/ioctl_helper.h"
#include "shared/source/os_interface/linux/os_time_linux.h"
#include "shared/source/os_interface/os_interface.h"
#include "shared/test/common/helpers/debug_manager_state_restore.h"
#include "shared/test/common/mocks/linux/mock_os_time_linux.h"
#include "shared/test/common/mocks/mock_execution_environment.h"
#include "shared/test/common/os_interface/linux/device_command_stream_fixture.h"
@@ -48,6 +49,8 @@ struct DrmTimeTest : public ::testing::Test {
osTime = MockOSTimeLinux::create(*rootDeviceEnvironment.osInterface);
osTime->setResolutionFunc(resolutionFuncTrue);
osTime->setGetTimeFunc(getTimeFuncTrue);
auto hwInfo = rootDeviceEnvironment.getMutableHardwareInfo();
osTime->setDeviceTimerResolution(*hwInfo);
deviceTime = osTime->getDeviceTime();
}
@@ -202,7 +205,7 @@ TEST_F(DrmTimeTest, givenGpuTimestampResolutionQueryWhenIoctlFailsThenDefaultRes
drm->getParamRetValue = 0;
drm->ioctlRes = -1;
deviceTime->callGetDynamicDeviceTimerResolution = true;
auto result = osTime->getDynamicDeviceTimerResolution(*defaultHwInfo);
EXPECT_DOUBLE_EQ(result, defaultResolution);
}
@@ -239,7 +242,7 @@ TEST_F(DrmTimeTest, givenGpuTimestampResolutionQueryWhenIoctlSuccedsThenCorrectR
// 19200000 is frequency yelding 52.083ns resolution
drm->getParamRetValue = 19200000;
drm->ioctlRes = 0;
deviceTime->callGetDynamicDeviceTimerResolution = true;
auto result = osTime->getDynamicDeviceTimerResolution(*defaultHwInfo);
EXPECT_DOUBLE_EQ(result, 52.08333333333333);
}
@@ -282,3 +285,46 @@ TEST_F(DrmTimeTest, whenGettingMaxGpuTimeStampValueThenHwInfoBasedValueIsReturne
EXPECT_EQ(0ull, osTime->getMaxGpuTimeStamp());
}
}
TEST_F(DrmTimeTest, whenGettingMaxGpuTimeStampValueWithinIntervalThenReuseFromPreviousCall) {
EXPECT_EQ(deviceTime->getGpuCpuTimeImplCalled, 0u);
TimeStampData gpuCpuTime;
osTime->getGpuCpuTime(&gpuCpuTime);
EXPECT_EQ(deviceTime->getGpuCpuTimeImplCalled, 1u);
auto gpuTimestampBefore = gpuCpuTime.gpuTimeStamp;
auto cpuTimeBefore = actualTime;
osTime->getGpuCpuTime(&gpuCpuTime);
EXPECT_EQ(deviceTime->getGpuCpuTimeImplCalled, 1u);
auto gpuTimestampAfter = gpuCpuTime.gpuTimeStamp;
auto cpuTimeAfter = actualTime;
auto cpuTimeDiff = cpuTimeAfter - cpuTimeBefore;
auto &rootDeviceEnvironment = *executionEnvironment.rootDeviceEnvironments[0];
auto hwInfo = rootDeviceEnvironment.getHardwareInfo();
auto deviceTimerResolution = deviceTime->getDynamicDeviceTimerResolution(*hwInfo);
auto gpuTimestampDiff = static_cast<uint64_t>(cpuTimeDiff / deviceTimerResolution);
EXPECT_EQ(gpuTimestampAfter, gpuTimestampBefore + gpuTimestampDiff);
}
TEST_F(DrmTimeTest, whenGettingMaxGpuTimeStampValueAfterIntervalThenCallToKmd) {
DebugManagerStateRestore restore;
debugManager.flags.GpuTimestampRefreshTimeout.set(0);
// Recreate mock to apply debug flag
auto &rootDeviceEnvironment = *executionEnvironment.rootDeviceEnvironments[0];
osTime = MockOSTimeLinux::create(*rootDeviceEnvironment.osInterface);
osTime->setResolutionFunc(resolutionFuncTrue);
osTime->setGetTimeFunc(getTimeFuncTrue);
auto deviceTime = osTime->getDeviceTime();
EXPECT_EQ(deviceTime->getGpuCpuTimeImplCalled, 0u);
TimeStampData gpuCpuTime;
osTime->getGpuCpuTime(&gpuCpuTime);
EXPECT_EQ(deviceTime->getGpuCpuTimeImplCalled, 1u);
osTime->getGpuCpuTime(&gpuCpuTime);
EXPECT_EQ(deviceTime->getGpuCpuTimeImplCalled, 2u);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2023 Intel Corporation
* Copyright (C) 2018-2024 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -29,10 +29,19 @@ BOOL WINAPI queryPerformanceCounterMock(
class MockDeviceTimeWin : public MockDeviceTime {
public:
bool getGpuCpuTimeImpl(TimeStampData *pGpuCpuTime, OSTime *osTime) override {
getGpuCpuTimeImplCalled++;
*pGpuCpuTime = gpuCpuTimeValue;
return true;
return getGpuCpuTimeImplResult;
}
double getDynamicDeviceTimerResolution(HardwareInfo const &hwInfo) const override {
return deviceTimerResolution;
}
bool getGpuCpuTimeImplResult = true;
TimeStampData gpuCpuTimeValue{};
uint32_t getGpuCpuTimeImplCalled = 0;
double deviceTimerResolution = 1;
};
struct OSTimeWinTest : public ::testing::Test {
@@ -196,3 +205,46 @@ TEST_F(OSTimeWinTest, whenGettingMaxGpuTimeStampValueThenHwInfoBasedValueIsRetur
EXPECT_EQ(0ull, osTime->getMaxGpuTimeStamp());
}
}
TEST_F(OSTimeWinTest, whenGettingMaxGpuTimeStampValueWithinIntervalThenReuseFromPreviousCall) {
osTime->overrideQueryPerformanceCounterFunction(queryPerformanceCounterMock);
LARGE_INTEGER frequency = {};
frequency.QuadPart = NSEC_PER_SEC;
osTime->setFrequency(frequency);
auto deviceTime = new MockDeviceTimeWin();
osTime->deviceTime.reset(deviceTime);
auto &rootDeviceEnvironment = *executionEnvironment.rootDeviceEnvironments[0];
auto hwInfo = rootDeviceEnvironment.getHardwareInfo();
osTime->setDeviceTimerResolution(*hwInfo);
EXPECT_EQ(deviceTime->getGpuCpuTimeImplCalled, 0u);
TimeStampData gpuCpuTime;
deviceTime->gpuCpuTimeValue = {1u, 1u};
valueToSet.QuadPart = 1;
osTime->getGpuCpuTime(&gpuCpuTime);
EXPECT_EQ(deviceTime->getGpuCpuTimeImplCalled, 1u);
auto gpuTimestampBefore = gpuCpuTime.gpuTimeStamp;
auto cpuTimeBefore = gpuCpuTime.cpuTimeinNS;
valueToSet.QuadPart = 5;
osTime->getGpuCpuTime(&gpuCpuTime);
EXPECT_EQ(deviceTime->getGpuCpuTimeImplCalled, 1u);
auto gpuTimestampAfter = gpuCpuTime.gpuTimeStamp;
auto cpuTimeAfter = gpuCpuTime.cpuTimeinNS;
auto cpuTimeDiff = cpuTimeAfter - cpuTimeBefore;
auto deviceTimerResolution = deviceTime->getDynamicDeviceTimerResolution(*hwInfo);
auto gpuTimestampDiff = static_cast<uint64_t>(cpuTimeDiff / deviceTimerResolution);
EXPECT_EQ(gpuTimestampAfter, gpuTimestampBefore + gpuTimestampDiff);
}
TEST_F(OSTimeWinTest, whenGetGpuCpuTimeFailedThenReturnFalse) {
TimeStampData gpuCpuTime;
auto deviceTime = new MockDeviceTimeWin();
osTime->deviceTime.reset(deviceTime);
deviceTime->getGpuCpuTimeImplResult = false;
EXPECT_FALSE(osTime->getGpuCpuTime(&gpuCpuTime));
}