mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-03 14:55:24 +08:00
Metrics Library Performance Counters implementation.
Signed-off-by: Piotr Maciejewski <piotr.maciejewski@intel.com> Change-Id: I0f00dca1892f4857baaebc75ba2208a4f33db1bf
This commit is contained in:
committed by
sys_ocldev
parent
369982995d
commit
d1d794c658
@@ -14,6 +14,8 @@ set(RUNTIME_SRCS_OS_INTERFACE_BASE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/debug_settings_manager.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/device_factory.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/device_factory.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/metrics_library.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/metrics_library.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_context.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_inc_base.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_interface.h
|
||||
|
||||
@@ -44,6 +44,7 @@ set(RUNTIME_SRCS_OS_INTERFACE_LINUX
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_library.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_library.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_memory_linux.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_metrics_library.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_thread_linux.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_thread_linux.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_time_linux.cpp
|
||||
|
||||
@@ -19,10 +19,6 @@ OSInterface::~OSInterface() {
|
||||
delete osInterfaceImpl;
|
||||
}
|
||||
|
||||
uint32_t OSInterface::getHwContextId() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool OSInterface::are64kbPagesEnabled() {
|
||||
return osEnabled64kbPages;
|
||||
}
|
||||
|
||||
51
runtime/os_interface/linux/os_metrics_library.cpp
Normal file
51
runtime/os_interface/linux/os_metrics_library.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2019 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "runtime/os_interface/metrics_library.h"
|
||||
|
||||
namespace NEO {
|
||||
//////////////////////////////////////////////////////
|
||||
// FUNCTION: MetricsLibrary::oaConfigurationActivate
|
||||
//////////////////////////////////////////////////////
|
||||
bool MetricsLibrary::oaConfigurationActivate(
|
||||
const ConfigurationHandle_1_0 &handle) {
|
||||
ConfigurationActivateData_1_0 data = {};
|
||||
data.Type = GpuConfigurationActivationType::Tbs;
|
||||
|
||||
return api->functions.ConfigurationActivate(
|
||||
handle,
|
||||
&data) == StatusCode::Success;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// FUNCTION: MetricsLibrary::oaConfigurationDeactivate
|
||||
//////////////////////////////////////////////////////
|
||||
bool MetricsLibrary::oaConfigurationDeactivate(
|
||||
const ConfigurationHandle_1_0 &handle) {
|
||||
return api->functions.ConfigurationDeactivate(
|
||||
handle) == StatusCode::Success;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// FUNCTION: MetricsLibrary::userConfigurationCreate
|
||||
//////////////////////////////////////////////////////
|
||||
bool MetricsLibrary::userConfigurationCreate(
|
||||
const ContextHandle_1_0 &context,
|
||||
ConfigurationHandle_1_0 &handle) {
|
||||
// Not supported on Linux.
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// FUNCTION: MetricsLibrary::userConfigurationDelete
|
||||
//////////////////////////////////////////////////////
|
||||
bool MetricsLibrary::userConfigurationDelete(
|
||||
const ConfigurationHandle_1_0 &handle) {
|
||||
// Not supported on Linux.
|
||||
return true;
|
||||
}
|
||||
} // namespace NEO
|
||||
@@ -7,66 +7,58 @@
|
||||
|
||||
#include "performance_counters_linux.h"
|
||||
|
||||
#include "runtime/device/device.h"
|
||||
#include "runtime/helpers/hw_helper.h"
|
||||
|
||||
namespace NEO {
|
||||
////////////////////////////////////////////////////
|
||||
// PerformanceCounters::create
|
||||
////////////////////////////////////////////////////
|
||||
std::unique_ptr<PerformanceCounters> PerformanceCounters::create(Device *device) {
|
||||
auto counter = std::make_unique<PerformanceCountersLinux>();
|
||||
auto gen = device->getHardwareInfo().platform.eRenderCoreFamily;
|
||||
auto &hwHelper = HwHelper::get(gen);
|
||||
UNRECOVERABLE_IF(counter == nullptr);
|
||||
|
||||
std::unique_ptr<PerformanceCounters> PerformanceCounters::create(OSTime *osTime) {
|
||||
return std::unique_ptr<PerformanceCounters>(new PerformanceCountersLinux(osTime));
|
||||
}
|
||||
PerformanceCountersLinux::PerformanceCountersLinux(OSTime *osTime) : PerformanceCounters(osTime) {
|
||||
mdLibHandle = nullptr;
|
||||
perfmonLoadConfigFunc = nullptr;
|
||||
counter->clientType.Gen = static_cast<MetricsLibraryApi::ClientGen>(hwHelper.getMetricsLibraryGenId());
|
||||
return counter;
|
||||
}
|
||||
|
||||
PerformanceCountersLinux::~PerformanceCountersLinux() {
|
||||
if (pAutoSamplingInterface) {
|
||||
autoSamplingStopFunc(&pAutoSamplingInterface);
|
||||
pAutoSamplingInterface = nullptr;
|
||||
available = false;
|
||||
}
|
||||
//////////////////////////////////////////////////////
|
||||
// PerformanceCountersLinux::enableCountersConfiguration
|
||||
//////////////////////////////////////////////////////
|
||||
bool PerformanceCountersLinux::enableCountersConfiguration() {
|
||||
// Release previous counters configuration so the user
|
||||
// can change configuration between kernels.
|
||||
releaseCountersConfiguration();
|
||||
|
||||
if (mdLibHandle) {
|
||||
dlcloseFunc(mdLibHandle);
|
||||
mdLibHandle = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void PerformanceCountersLinux::initialize(const HardwareInfo *hwInfo) {
|
||||
PerformanceCounters::initialize(hwInfo);
|
||||
mdLibHandle = dlopenFunc("libmd.so", RTLD_LAZY | RTLD_LOCAL);
|
||||
if (mdLibHandle) {
|
||||
perfmonLoadConfigFunc = reinterpret_cast<perfmonLoadConfig_t>(dlsymFunc(mdLibHandle, "drm_intel_perfmon_load_config"));
|
||||
}
|
||||
setPlatformInfoFunc(hwInfo->platform.eProductFamily, (void *)(&hwInfo->featureTable));
|
||||
}
|
||||
|
||||
void PerformanceCountersLinux::enableImpl() {
|
||||
if (mdLibHandle && perfmonLoadConfigFunc) {
|
||||
PerformanceCounters::enableImpl();
|
||||
}
|
||||
}
|
||||
|
||||
bool PerformanceCountersLinux::verifyPmRegsCfg(InstrPmRegsCfg *pCfg, uint32_t *pLastPmRegsCfgHandle, bool *pLastPmRegsCfgPending) {
|
||||
if (perfmonLoadConfigFunc == nullptr) {
|
||||
// Create oa configuration.
|
||||
if (!metricsLibrary->oaConfigurationCreate(
|
||||
context,
|
||||
oaConfiguration)) {
|
||||
DEBUG_BREAK_IF(true);
|
||||
return false;
|
||||
}
|
||||
if (PerformanceCounters::verifyPmRegsCfg(pCfg, pLastPmRegsCfgHandle, pLastPmRegsCfgPending)) {
|
||||
return getPerfmonConfig(pCfg);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool PerformanceCountersLinux::getPerfmonConfig(InstrPmRegsCfg *pCfg) {
|
||||
unsigned int oaCfgHandle = pCfg->OaCounters.Handle;
|
||||
unsigned int gpCfgHandle = pCfg->GpCounters.Handle;
|
||||
int fd = osInterface->get()->getDrm()->getFileDescriptor();
|
||||
if (perfmonLoadConfigFunc(fd, nullptr, &oaCfgHandle, &gpCfgHandle) != 0) {
|
||||
return false;
|
||||
}
|
||||
if (pCfg->OaCounters.Handle != 0 && oaCfgHandle != pCfg->OaCounters.Handle) {
|
||||
return false;
|
||||
}
|
||||
if (pCfg->GpCounters.Handle != 0 && gpCfgHandle != pCfg->GpCounters.Handle) {
|
||||
|
||||
// Enable oa configuration.
|
||||
if (!metricsLibrary->oaConfigurationActivate(
|
||||
oaConfiguration)) {
|
||||
DEBUG_BREAK_IF(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// PerformanceCountersLinux::releaseCountersConfiguration
|
||||
//////////////////////////////////////////////////////
|
||||
void PerformanceCountersLinux::releaseCountersConfiguration() {
|
||||
// Oa configuration.
|
||||
if (oaConfiguration.IsValid()) {
|
||||
metricsLibrary->oaConfigurationDeactivate(oaConfiguration);
|
||||
metricsLibrary->oaConfigurationDelete(oaConfiguration);
|
||||
oaConfiguration.data = nullptr;
|
||||
}
|
||||
}
|
||||
} // namespace NEO
|
||||
|
||||
@@ -8,35 +8,17 @@
|
||||
#pragma once
|
||||
#include "runtime/os_interface/performance_counters.h"
|
||||
|
||||
#include "os_interface.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
typedef struct _drm_intel_context drm_intel_context;
|
||||
|
||||
namespace NEO {
|
||||
|
||||
class PerformanceCountersLinux : virtual public PerformanceCounters {
|
||||
public:
|
||||
PerformanceCountersLinux(OSTime *osTime);
|
||||
~PerformanceCountersLinux() override;
|
||||
void initialize(const HardwareInfo *hwInfo) override;
|
||||
void enableImpl() override;
|
||||
PerformanceCountersLinux() = default;
|
||||
~PerformanceCountersLinux() override = default;
|
||||
|
||||
protected:
|
||||
virtual bool getPerfmonConfig(InstrPmRegsCfg *pCfg);
|
||||
bool verifyPmRegsCfg(InstrPmRegsCfg *pCfg, uint32_t *pLastPmRegsCfgHandle, bool *pLastPmRegsCfgPending) override;
|
||||
|
||||
typedef int (*perfmonLoadConfig_t)(int fd, drm_intel_context *ctx, uint32_t *oaCfgId, uint32_t *gpCfgId);
|
||||
typedef void *(*dlopenFunc_t)(const char *, int);
|
||||
typedef void *(*dlsymFunc_t)(void *, const char *);
|
||||
|
||||
void *mdLibHandle;
|
||||
|
||||
perfmonLoadConfig_t perfmonLoadConfigFunc;
|
||||
dlopenFunc_t dlopenFunc = dlopen;
|
||||
dlsymFunc_t dlsymFunc = dlsym;
|
||||
decltype(&dlclose) dlcloseFunc = dlclose;
|
||||
decltype(&instrSetPlatformInfo) setPlatformInfoFunc = instrSetPlatformInfo;
|
||||
/////////////////////////////////////////////////////
|
||||
// Gpu oa/mmio configuration.
|
||||
/////////////////////////////////////////////////////
|
||||
bool enableCountersConfiguration() override;
|
||||
void releaseCountersConfiguration() override;
|
||||
};
|
||||
} // namespace NEO
|
||||
|
||||
188
runtime/os_interface/metrics_library.cpp
Normal file
188
runtime/os_interface/metrics_library.cpp
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2019 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "runtime/os_interface/metrics_library.h"
|
||||
|
||||
#include "runtime/helpers/hw_helper.h"
|
||||
#include "runtime/os_interface/os_inc_base.h"
|
||||
|
||||
namespace NEO {
|
||||
///////////////////////////////////////////////////////
|
||||
// FUNCTION: MetricsLibrary::MetricsLibrary
|
||||
///////////////////////////////////////////////////////
|
||||
MetricsLibrary::MetricsLibrary() {
|
||||
api = std::make_unique<MetricsLibraryInterface>();
|
||||
osLibrary.reset(OsLibrary::load(Os::metricsLibraryDllName));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// FUNCTION: MetricsLibrary::open
|
||||
//////////////////////////////////////////////////////
|
||||
bool MetricsLibrary::open() {
|
||||
|
||||
UNRECOVERABLE_IF(osLibrary.get() == nullptr);
|
||||
|
||||
if (osLibrary->isLoaded()) {
|
||||
api->contextCreate = reinterpret_cast<ContextCreateFunction_1_0>(osLibrary->getProcAddress(METRICS_LIBRARY_CONTEXT_CREATE_1_0));
|
||||
api->contextDelete = reinterpret_cast<ContextDeleteFunction_1_0>(osLibrary->getProcAddress(METRICS_LIBRARY_CONTEXT_DELETE_1_0));
|
||||
} else {
|
||||
api->contextCreate = nullptr;
|
||||
api->contextDelete = nullptr;
|
||||
}
|
||||
|
||||
if (!api->contextCreate) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!api->contextDelete) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// MetricsLibrary::createContext
|
||||
//////////////////////////////////////////////////////
|
||||
bool MetricsLibrary::contextCreate(
|
||||
const ClientType_1_0 &clientType,
|
||||
ClientData_1_0 &clientData,
|
||||
ContextCreateData_1_0 &createData,
|
||||
ContextHandle_1_0 &handle) {
|
||||
|
||||
createData.Api = &api->functions;
|
||||
createData.ClientCallbacks = &api->callbacks;
|
||||
createData.ClientData = &clientData;
|
||||
|
||||
return api->contextCreate(
|
||||
clientType,
|
||||
&createData,
|
||||
&handle) == StatusCode::Success;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// MetricsLibrary::contextDelete
|
||||
//////////////////////////////////////////////////////
|
||||
bool MetricsLibrary::contextDelete(
|
||||
const ContextHandle_1_0 &handle) {
|
||||
return api->contextDelete(handle) == StatusCode::Success;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// MetricsLibrary::hwCountersCreate
|
||||
//////////////////////////////////////////////////////
|
||||
bool MetricsLibrary::hwCountersCreate(
|
||||
const ContextHandle_1_0 &context,
|
||||
const uint32_t slots,
|
||||
const ConfigurationHandle_1_0 user,
|
||||
QueryHandle_1_0 &query) {
|
||||
QueryCreateData_1_0 data = {};
|
||||
data.HandleContext = context;
|
||||
data.Type = ObjectType::QueryHwCounters;
|
||||
data.Slots = slots;
|
||||
|
||||
return api->functions.QueryCreate(
|
||||
&data,
|
||||
&query) == StatusCode::Success;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// MetricsLibrary::hwCountersDelete
|
||||
//////////////////////////////////////////////////////
|
||||
bool MetricsLibrary::hwCountersDelete(
|
||||
const QueryHandle_1_0 &query) {
|
||||
return api->functions.QueryDelete(query) == StatusCode::Success;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// MetricsLibrary::hwCountersGetReport
|
||||
//////////////////////////////////////////////////////
|
||||
bool MetricsLibrary::hwCountersGetReport(
|
||||
const QueryHandle_1_0 &handle,
|
||||
const uint32_t slot,
|
||||
const uint32_t slotsCount,
|
||||
const uint32_t dataSize,
|
||||
void *data) {
|
||||
GetReportData_1_0 report = {};
|
||||
report.Type = ObjectType::QueryHwCounters;
|
||||
report.Query.Handle = handle;
|
||||
report.Query.Slot = slot;
|
||||
report.Query.SlotsCount = slotsCount;
|
||||
report.Query.Data = data;
|
||||
report.Query.DataSize = dataSize;
|
||||
|
||||
return api->functions.GetData(&report) == StatusCode::Success;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// MetricsLibrary::hwCountersGetApiReportSize
|
||||
//////////////////////////////////////////////////////
|
||||
uint32_t MetricsLibrary::hwCountersGetApiReportSize() {
|
||||
ValueType type = ValueType::Uint32;
|
||||
TypedValue_1_0 value = {};
|
||||
|
||||
return api->functions.GetParameter(ParameterType::QueryHwCountersReportApiSize, &type, &value) == StatusCode::Success
|
||||
? value.ValueUInt32
|
||||
: 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// MetricsLibrary::hwCountersGetGpuReportSize
|
||||
//////////////////////////////////////////////////////
|
||||
uint32_t MetricsLibrary::hwCountersGetGpuReportSize() {
|
||||
ValueType type = ValueType::Uint32;
|
||||
TypedValue_1_0 value = {};
|
||||
|
||||
return api->functions.GetParameter(ParameterType::QueryHwCountersReportGpuSize, &type, &value) == StatusCode::Success
|
||||
? value.ValueUInt32
|
||||
: 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// MetricsLibrary::commandBufferGet
|
||||
//////////////////////////////////////////////////////
|
||||
bool MetricsLibrary::commandBufferGet(
|
||||
CommandBufferData_1_0 &data) {
|
||||
return api->functions.CommandBufferGet(
|
||||
&data) == StatusCode::Success;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// MetricsLibrary::commandBufferGetSize
|
||||
//////////////////////////////////////////////////////
|
||||
bool MetricsLibrary::commandBufferGetSize(
|
||||
const CommandBufferData_1_0 &commandBufferData,
|
||||
CommandBufferSize_1_0 &commandBufferSize) {
|
||||
return api->functions.CommandBufferGetSize(
|
||||
&commandBufferData,
|
||||
&commandBufferSize) == StatusCode::Success;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// MetricsLibrary::oaConfigurationCreate
|
||||
//////////////////////////////////////////////////////
|
||||
bool MetricsLibrary::oaConfigurationCreate(
|
||||
const ContextHandle_1_0 &context,
|
||||
ConfigurationHandle_1_0 &handle) {
|
||||
ConfigurationCreateData_1_0 data = {};
|
||||
data.HandleContext = context;
|
||||
data.Type = ObjectType::ConfigurationHwCountersOa;
|
||||
|
||||
return api->functions.ConfigurationCreate(
|
||||
&data,
|
||||
&handle) == StatusCode::Success;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// MetricsLibrary::oaConfigurationDelete
|
||||
//////////////////////////////////////////////////////
|
||||
bool MetricsLibrary::oaConfigurationDelete(
|
||||
const ConfigurationHandle_1_0 &handle) {
|
||||
|
||||
return api->functions.ConfigurationDelete(handle) == StatusCode::Success;
|
||||
}
|
||||
} // namespace NEO
|
||||
89
runtime/os_interface/metrics_library.h
Normal file
89
runtime/os_interface/metrics_library.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2019 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "runtime/os_interface/os_library.h"
|
||||
|
||||
#include "instrumentation.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace NEO {
|
||||
|
||||
using MetricsLibraryApi::ClientApi;
|
||||
using MetricsLibraryApi::ClientCallbacks_1_0;
|
||||
using MetricsLibraryApi::ClientData_1_0;
|
||||
using MetricsLibraryApi::ClientGen;
|
||||
using MetricsLibraryApi::ClientType_1_0;
|
||||
using MetricsLibraryApi::CommandBufferData_1_0;
|
||||
using MetricsLibraryApi::CommandBufferSize_1_0;
|
||||
using MetricsLibraryApi::ConfigurationActivateData_1_0;
|
||||
using MetricsLibraryApi::ConfigurationCreateData_1_0;
|
||||
using MetricsLibraryApi::ConfigurationHandle_1_0;
|
||||
using MetricsLibraryApi::ContextCreateData_1_0;
|
||||
using MetricsLibraryApi::ContextCreateFunction_1_0;
|
||||
using MetricsLibraryApi::ContextDeleteFunction_1_0;
|
||||
using MetricsLibraryApi::ContextHandle_1_0;
|
||||
using MetricsLibraryApi::GetReportData_1_0;
|
||||
using MetricsLibraryApi::GpuConfigurationActivationType;
|
||||
using MetricsLibraryApi::GpuMemory_1_0;
|
||||
using MetricsLibraryApi::Interface_1_0;
|
||||
using MetricsLibraryApi::ObjectType;
|
||||
using MetricsLibraryApi::ParameterType;
|
||||
using MetricsLibraryApi::QueryCreateData_1_0;
|
||||
using MetricsLibraryApi::QueryHandle_1_0;
|
||||
using MetricsLibraryApi::StatusCode;
|
||||
using MetricsLibraryApi::TypedValue_1_0;
|
||||
using MetricsLibraryApi::ValueType;
|
||||
|
||||
class MetricsLibraryInterface {
|
||||
public:
|
||||
ContextCreateFunction_1_0 contextCreate = nullptr;
|
||||
ContextDeleteFunction_1_0 contextDelete = nullptr;
|
||||
Interface_1_0 functions = {};
|
||||
ClientCallbacks_1_0 callbacks = {};
|
||||
};
|
||||
|
||||
class MetricsLibrary {
|
||||
public:
|
||||
MetricsLibrary();
|
||||
MOCKABLE_VIRTUAL ~MetricsLibrary(){};
|
||||
|
||||
// Library open function.
|
||||
MOCKABLE_VIRTUAL bool open();
|
||||
|
||||
// Context create / destroy functions.
|
||||
MOCKABLE_VIRTUAL bool contextCreate(const ClientType_1_0 &client, ClientData_1_0 &clientData, ContextCreateData_1_0 &createData, ContextHandle_1_0 &handle);
|
||||
MOCKABLE_VIRTUAL bool contextDelete(const ContextHandle_1_0 &handle);
|
||||
|
||||
// HwCounters functions.
|
||||
MOCKABLE_VIRTUAL bool hwCountersCreate(const ContextHandle_1_0 &context, const uint32_t slots, const ConfigurationHandle_1_0 mmio, QueryHandle_1_0 &handle);
|
||||
MOCKABLE_VIRTUAL bool hwCountersDelete(const QueryHandle_1_0 &handle);
|
||||
MOCKABLE_VIRTUAL bool hwCountersGetReport(const QueryHandle_1_0 &handle, const uint32_t slot, const uint32_t slotsCount, const uint32_t dataSize, void *data);
|
||||
MOCKABLE_VIRTUAL uint32_t hwCountersGetApiReportSize();
|
||||
MOCKABLE_VIRTUAL uint32_t hwCountersGetGpuReportSize();
|
||||
|
||||
// Oa configuration functions.
|
||||
MOCKABLE_VIRTUAL bool oaConfigurationCreate(const ContextHandle_1_0 &context, ConfigurationHandle_1_0 &handle);
|
||||
MOCKABLE_VIRTUAL bool oaConfigurationDelete(const ConfigurationHandle_1_0 &handle);
|
||||
MOCKABLE_VIRTUAL bool oaConfigurationActivate(const ConfigurationHandle_1_0 &handle);
|
||||
MOCKABLE_VIRTUAL bool oaConfigurationDeactivate(const ConfigurationHandle_1_0 &handle);
|
||||
|
||||
// User mmio configuration functions.
|
||||
MOCKABLE_VIRTUAL bool userConfigurationCreate(const ContextHandle_1_0 &context, ConfigurationHandle_1_0 &handle);
|
||||
MOCKABLE_VIRTUAL bool userConfigurationDelete(const ConfigurationHandle_1_0 &handle);
|
||||
|
||||
// Command buffer functions.
|
||||
MOCKABLE_VIRTUAL bool commandBufferGet(CommandBufferData_1_0 &data);
|
||||
MOCKABLE_VIRTUAL bool commandBufferGetSize(const CommandBufferData_1_0 &commandBufferData, CommandBufferSize_1_0 &commandBufferSize);
|
||||
|
||||
public:
|
||||
std::unique_ptr<OsLibrary> osLibrary;
|
||||
std::unique_ptr<MetricsLibraryInterface> api;
|
||||
};
|
||||
} // namespace NEO
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2018 Intel Corporation
|
||||
* Copyright (C) 2017-2019 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -18,4 +18,7 @@ extern const char *testDllName;
|
||||
extern const char *fileSeparator;
|
||||
// Pci Path
|
||||
extern const char *sysFsPciPath;
|
||||
|
||||
// Os specific Metrics Library name
|
||||
extern const char *metricsLibraryDllName;
|
||||
}; // namespace Os
|
||||
|
||||
@@ -21,7 +21,6 @@ class OSInterface {
|
||||
OSInterfaceImpl *get() const {
|
||||
return osInterfaceImpl;
|
||||
};
|
||||
unsigned int getHwContextId() const;
|
||||
static bool osEnabled64kbPages;
|
||||
static bool osEnableLocalMemory;
|
||||
static bool are64kbPagesEnabled();
|
||||
|
||||
@@ -7,175 +7,240 @@
|
||||
|
||||
#include "runtime/os_interface/performance_counters.h"
|
||||
|
||||
#include "runtime/helpers/debug_helpers.h"
|
||||
#include "runtime/os_interface/os_interface.h"
|
||||
#include "runtime/os_interface/os_time.h"
|
||||
#include "runtime/utilities/tag_allocator.h"
|
||||
|
||||
#include "CL/cl.h"
|
||||
using namespace MetricsLibraryApi;
|
||||
|
||||
namespace NEO {
|
||||
decltype(&instrGetPerfCountersQueryData) getPerfCountersQueryDataFactory[IGFX_MAX_CORE] = {
|
||||
nullptr,
|
||||
};
|
||||
size_t perfCountersQuerySize[IGFX_MAX_CORE] = {
|
||||
0,
|
||||
};
|
||||
|
||||
PerformanceCounters::PerformanceCounters(OSTime *osTime) {
|
||||
this->osTime = osTime;
|
||||
DEBUG_BREAK_IF(osTime == nullptr);
|
||||
gfxFamily = IGFX_UNKNOWN_CORE;
|
||||
cbData = {
|
||||
0,
|
||||
};
|
||||
this->osInterface = osTime->getOSInterface();
|
||||
hwMetricsEnabled = false;
|
||||
useMIRPC = false;
|
||||
pAutoSamplingInterface = nullptr;
|
||||
cpuRawTimestamp = 0;
|
||||
refCounter = 0;
|
||||
available = false;
|
||||
reportId = 0;
|
||||
//////////////////////////////////////////////////////
|
||||
// PerformanceCounters constructor.
|
||||
//////////////////////////////////////////////////////
|
||||
PerformanceCounters::PerformanceCounters() {
|
||||
metricsLibrary = std::make_unique<MetricsLibrary>();
|
||||
UNRECOVERABLE_IF(metricsLibrary == nullptr);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// PerformanceCounters::getReferenceNumber
|
||||
//////////////////////////////////////////////////////
|
||||
uint32_t PerformanceCounters::getReferenceNumber() {
|
||||
std::lock_guard<std::mutex> lockMutex(mutex);
|
||||
return referenceCounter;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// PerformanceCounters::isAvailable
|
||||
//////////////////////////////////////////////////////
|
||||
bool PerformanceCounters::isAvailable() {
|
||||
return available;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// PerformanceCounters::enable
|
||||
//////////////////////////////////////////////////////
|
||||
void PerformanceCounters::enable() {
|
||||
mutex.lock();
|
||||
std::lock_guard<std::mutex> lg(mutex, std::adopt_lock);
|
||||
if (refCounter == 0) {
|
||||
enableImpl();
|
||||
std::lock_guard<std::mutex> lockMutex(mutex);
|
||||
|
||||
if (referenceCounter == 0) {
|
||||
available = openMetricsLibrary();
|
||||
}
|
||||
refCounter++;
|
||||
|
||||
referenceCounter++;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// PerformanceCounters::shutdown
|
||||
//////////////////////////////////////////////////////
|
||||
void PerformanceCounters::shutdown() {
|
||||
mutex.lock();
|
||||
std::lock_guard<std::mutex> lg(mutex, std::adopt_lock);
|
||||
if (refCounter >= 1) {
|
||||
if (refCounter == 1) {
|
||||
shutdownImpl();
|
||||
std::lock_guard<std::mutex> lockMutex(mutex);
|
||||
|
||||
if (referenceCounter >= 1) {
|
||||
if (referenceCounter == 1) {
|
||||
available = false;
|
||||
closeMetricsLibrary();
|
||||
}
|
||||
refCounter--;
|
||||
referenceCounter--;
|
||||
}
|
||||
}
|
||||
|
||||
void PerformanceCounters::initialize(const HardwareInfo *hwInfo) {
|
||||
useMIRPC = !(hwInfo->workaroundTable.waDoNotUseMIReportPerfCount);
|
||||
gfxFamily = hwInfo->platform.eRenderCoreFamily;
|
||||
//////////////////////////////////////////////////////
|
||||
// PerformanceCounters::getMetricsLibraryInterface
|
||||
//////////////////////////////////////////////////////
|
||||
MetricsLibrary *PerformanceCounters::getMetricsLibraryInterface() {
|
||||
return metricsLibrary.get();
|
||||
}
|
||||
|
||||
if (getPerfCountersQueryDataFactory[gfxFamily] != nullptr) {
|
||||
getPerfCountersQueryDataFunc = getPerfCountersQueryDataFactory[gfxFamily];
|
||||
} else {
|
||||
perfCountersQuerySize[gfxFamily] = sizeof(GTDI_QUERY);
|
||||
//////////////////////////////////////////////////////
|
||||
// PerformanceCounters::setMetricsLibraryInterface
|
||||
//////////////////////////////////////////////////////
|
||||
void PerformanceCounters::setMetricsLibraryInterface(std::unique_ptr<MetricsLibrary> newMetricsLibrary) {
|
||||
metricsLibrary = std::move(newMetricsLibrary);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// PerformanceCounters::getMetricsLibraryContext
|
||||
//////////////////////////////////////////////////////
|
||||
ContextHandle_1_0 PerformanceCounters::getMetricsLibraryContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// PerformanceCounters::openMetricsLibrary
|
||||
//////////////////////////////////////////////////////
|
||||
bool PerformanceCounters::openMetricsLibrary() {
|
||||
|
||||
// Open metrics library.
|
||||
bool result = metricsLibrary->open();
|
||||
DEBUG_BREAK_IF(!result);
|
||||
|
||||
// Create metrics library context.
|
||||
if (result) {
|
||||
result = metricsLibrary->contextCreate(
|
||||
clientType,
|
||||
clientData,
|
||||
contextData,
|
||||
context);
|
||||
|
||||
// Validate gpu report size.
|
||||
DEBUG_BREAK_IF(!metricsLibrary->hwCountersGetGpuReportSize());
|
||||
}
|
||||
|
||||
// Error handling.
|
||||
if (!result) {
|
||||
closeMetricsLibrary();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// PerformanceCounters::closeMetricsLibrary
|
||||
//////////////////////////////////////////////////////
|
||||
void PerformanceCounters::closeMetricsLibrary() {
|
||||
// Destroy oa/user mmio configuration.
|
||||
releaseCountersConfiguration();
|
||||
|
||||
// Destroy hw counters query.
|
||||
if (query.IsValid()) {
|
||||
metricsLibrary->hwCountersDelete(query);
|
||||
}
|
||||
|
||||
// Destroy metrics library context.
|
||||
if (context.IsValid()) {
|
||||
metricsLibrary->contextDelete(context);
|
||||
}
|
||||
}
|
||||
void PerformanceCounters::enableImpl() {
|
||||
hwMetricsEnabled = hwMetricsEnableFunc(cbData, true);
|
||||
|
||||
if (!pAutoSamplingInterface && hwMetricsEnabled) {
|
||||
autoSamplingStartFunc(cbData, &pAutoSamplingInterface);
|
||||
if (pAutoSamplingInterface) {
|
||||
available = true;
|
||||
//////////////////////////////////////////////////////
|
||||
// PerformanceCounters::getQueryHandle
|
||||
//////////////////////////////////////////////////////
|
||||
QueryHandle_1_0 PerformanceCounters::getQueryHandle() {
|
||||
if (!query.IsValid()) {
|
||||
metricsLibrary->hwCountersCreate(
|
||||
context,
|
||||
1,
|
||||
userConfiguration,
|
||||
query);
|
||||
}
|
||||
|
||||
DEBUG_BREAK_IF(!query.IsValid());
|
||||
return query;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// PerformanceCounters::getGpuCommandsSize
|
||||
//////////////////////////////////////////////////////
|
||||
uint32_t PerformanceCounters::getGpuCommandsSize(
|
||||
const bool begin) {
|
||||
CommandBufferData_1_0 bufferData = {};
|
||||
CommandBufferSize_1_0 bufferSize = {};
|
||||
|
||||
if (begin) {
|
||||
// Load currently activated (through metrics discovery) oa/user mmio configuration and use it.
|
||||
// It will allow to change counters configuration between subsequent clEnqueueNDCommandRange calls.
|
||||
if (!enableCountersConfiguration()) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bufferData.HandleContext = context;
|
||||
bufferData.Type = GpuCommandBufferType::Render;
|
||||
bufferData.CommandsType = ObjectType::QueryHwCounters;
|
||||
|
||||
bufferData.QueryHwCounters.Begin = begin;
|
||||
bufferData.QueryHwCounters.Handle = getQueryHandle();
|
||||
bufferData.QueryHwCounters.HandleUserConfiguration = userConfiguration;
|
||||
|
||||
return metricsLibrary->commandBufferGetSize(bufferData, bufferSize)
|
||||
? bufferSize.GpuMemorySize
|
||||
: 0;
|
||||
}
|
||||
void PerformanceCounters::shutdownImpl() {
|
||||
if (hwMetricsEnabled) {
|
||||
hwMetricsEnableFunc(cbData, false);
|
||||
hwMetricsEnabled = false;
|
||||
}
|
||||
if (pAutoSamplingInterface) {
|
||||
autoSamplingStopFunc(&pAutoSamplingInterface);
|
||||
pAutoSamplingInterface = nullptr;
|
||||
available = false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// PerformanceCounters::getGpuCommands
|
||||
//////////////////////////////////////////////////////
|
||||
bool PerformanceCounters::getGpuCommands(
|
||||
TagNode<HwPerfCounter> &performanceCounters,
|
||||
const bool begin,
|
||||
const uint32_t bufferSize,
|
||||
void *pBuffer) {
|
||||
// Command Buffer data.
|
||||
CommandBufferData_1_0 bufferData = {};
|
||||
bufferData.HandleContext = context;
|
||||
bufferData.Type = GpuCommandBufferType::Render;
|
||||
bufferData.CommandsType = ObjectType::QueryHwCounters;
|
||||
bufferData.Data = pBuffer;
|
||||
bufferData.Size = bufferSize;
|
||||
|
||||
// Gpu memory allocation for query hw counters.
|
||||
bufferData.Allocation.CpuAddress = reinterpret_cast<uint8_t *>(performanceCounters.tagForCpuAccess);
|
||||
bufferData.Allocation.GpuAddress = performanceCounters.getGpuAddress();
|
||||
|
||||
// Query hw counters specific data.
|
||||
bufferData.QueryHwCounters.Begin = begin;
|
||||
bufferData.QueryHwCounters.Handle = getQueryHandle();
|
||||
bufferData.QueryHwCounters.HandleUserConfiguration = userConfiguration;
|
||||
|
||||
return metricsLibrary->commandBufferGet(bufferData);
|
||||
}
|
||||
void PerformanceCounters::setCpuTimestamp() {
|
||||
cpuRawTimestamp = osTime->getCpuRawTimestamp();
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// PerformanceCounters::getApiReportSize
|
||||
//////////////////////////////////////////////////////
|
||||
uint32_t PerformanceCounters::getApiReportSize() {
|
||||
return metricsLibrary->hwCountersGetApiReportSize();
|
||||
}
|
||||
InstrPmRegsCfg *PerformanceCounters::getPmRegsCfg(uint32_t configuration) {
|
||||
if (!hwMetricsEnabled) {
|
||||
return nullptr;
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// PerformanceCounters::getGpuReportSize
|
||||
//////////////////////////////////////////////////////
|
||||
uint32_t PerformanceCounters::getGpuReportSize() {
|
||||
return metricsLibrary->hwCountersGetGpuReportSize();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// PerformanceCounters::getApiReport
|
||||
//////////////////////////////////////////////////////
|
||||
bool PerformanceCounters::getApiReport(const size_t inputParamSize, void *pInputParam, size_t *pOutputParamSize, bool isEventComplete) {
|
||||
const uint32_t outputSize = metricsLibrary->hwCountersGetApiReportSize();
|
||||
|
||||
if (pOutputParamSize) {
|
||||
*pOutputParamSize = outputSize;
|
||||
}
|
||||
|
||||
switch (configuration) {
|
||||
case GTDI_CONFIGURATION_SET_DYNAMIC:
|
||||
case GTDI_CONFIGURATION_SET_1:
|
||||
case GTDI_CONFIGURATION_SET_2:
|
||||
case GTDI_CONFIGURATION_SET_3:
|
||||
break;
|
||||
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
InstrPmRegsCfg *pPmRegsCfg = new InstrPmRegsCfg();
|
||||
pPmRegsCfg->OaCounters.Handle = INSTR_PM_REGS_CFG_INVALID;
|
||||
|
||||
mutex.lock();
|
||||
std::lock_guard<std::mutex> lg(mutex, std::adopt_lock);
|
||||
|
||||
if (getPmRegsCfgFunc(cbData, configuration, pPmRegsCfg, nullptr)) {
|
||||
return pPmRegsCfg;
|
||||
}
|
||||
delete pPmRegsCfg;
|
||||
return nullptr;
|
||||
}
|
||||
bool PerformanceCounters::verifyPmRegsCfg(InstrPmRegsCfg *pCfg, uint32_t *pLastPmRegsCfgHandle, bool *pLastPmRegsCfgPending) {
|
||||
if (pCfg == nullptr || pLastPmRegsCfgHandle == nullptr || pLastPmRegsCfgPending == nullptr) {
|
||||
return false;
|
||||
}
|
||||
if (checkPmRegsCfgFunc(pCfg, pLastPmRegsCfgHandle, pAutoSamplingInterface)) {
|
||||
if (loadPmRegsCfgFunc(cbData, pCfg, 1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool PerformanceCounters::sendPmRegsCfgCommands(InstrPmRegsCfg *pCfg, uint32_t *pLastPmRegsCfgHandle, bool *pLastPmRegsCfgPending) {
|
||||
if (verifyPmRegsCfg(pCfg, pLastPmRegsCfgHandle, pLastPmRegsCfgPending)) {
|
||||
*pLastPmRegsCfgPending = true;
|
||||
if (pInputParam == nullptr && inputParamSize == 0 && pOutputParamSize) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool PerformanceCounters::processEventReport(size_t inputParamSize, void *inputParam, size_t *outputParamSize, HwPerfCounter *pPrivateData, InstrPmRegsCfg *countersConfiguration, bool isEventComplete) {
|
||||
size_t outputSize = perfCountersQuerySize[gfxFamily];
|
||||
if (outputParamSize) {
|
||||
*outputParamSize = outputSize;
|
||||
}
|
||||
if (inputParam == nullptr && inputParamSize == 0 && outputParamSize) {
|
||||
return true;
|
||||
}
|
||||
if (inputParam == nullptr || isEventComplete == false) {
|
||||
|
||||
if (pInputParam == nullptr || isEventComplete == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (inputParamSize < outputSize) {
|
||||
return false;
|
||||
}
|
||||
GTDI_QUERY *pClientData = static_cast<GTDI_QUERY *>(inputParam);
|
||||
getPerfCountersQueryDataFunc(cbData, pClientData, &pPrivateData->HWPerfCounters,
|
||||
cpuRawTimestamp, pAutoSamplingInterface, countersConfiguration, useMIRPC, true, nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
int PerformanceCounters::sendPerfConfiguration(uint32_t count, uint32_t *pOffsets, uint32_t *pValues) {
|
||||
bool ret = false;
|
||||
|
||||
if (count == 0 || pOffsets == NULL || pValues == NULL) {
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
|
||||
mutex.lock();
|
||||
std::lock_guard<std::mutex> lg(mutex, std::adopt_lock);
|
||||
if (pOffsets[0] != INSTR_READ_REGS_CFG_TAG) {
|
||||
ret = setPmRegsCfgFunc(cbData, count, pOffsets, pValues);
|
||||
} else if (count > 1) {
|
||||
ret = sendReadRegsCfgFunc(cbData, count - 1, pOffsets + 1, pValues + 1);
|
||||
}
|
||||
|
||||
return ret ? CL_SUCCESS : CL_PROFILING_INFO_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
uint32_t PerformanceCounters::getCurrentReportId() {
|
||||
return (osInterface->getHwContextId() << 12) | getReportId();
|
||||
return metricsLibrary->hwCountersGetReport(query, 0, 1, outputSize, pInputParam);
|
||||
}
|
||||
} // namespace NEO
|
||||
|
||||
@@ -7,71 +7,105 @@
|
||||
|
||||
#pragma once
|
||||
#include "runtime/event/perf_counter.h"
|
||||
#include "runtime/helpers/hw_info.h"
|
||||
#include "runtime/os_interface/metrics_library.h"
|
||||
|
||||
#include "CL/cl.h"
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
namespace NEO {
|
||||
struct HardwareInfo;
|
||||
class OSInterface;
|
||||
class OSTime;
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// Forward declaration.
|
||||
//////////////////////////////////////////////////////
|
||||
template <typename Node>
|
||||
struct TagNode;
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// Performance counters implementation.
|
||||
//////////////////////////////////////////////////////
|
||||
class PerformanceCounters {
|
||||
public:
|
||||
static std::unique_ptr<PerformanceCounters> create(OSTime *osTime);
|
||||
//////////////////////////////////////////////////////
|
||||
// Constructor/destructor.
|
||||
//////////////////////////////////////////////////////
|
||||
PerformanceCounters();
|
||||
virtual ~PerformanceCounters() = default;
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// Performance counters creation.
|
||||
//////////////////////////////////////////////////////
|
||||
static std::unique_ptr<PerformanceCounters> create(class Device *device);
|
||||
void enable();
|
||||
void shutdown();
|
||||
virtual void initialize(const HardwareInfo *hwInfo);
|
||||
InstrPmRegsCfg *getPmRegsCfg(uint32_t configuration);
|
||||
bool sendPmRegsCfgCommands(InstrPmRegsCfg *pCfg, uint32_t *pLastPmRegsCfgHandle, bool *pLastPmRegsCfgPending);
|
||||
void setCpuTimestamp();
|
||||
bool processEventReport(size_t pClientDataSize, void *pClientData, size_t *outputSize, HwPerfCounter *pPrivateData, InstrPmRegsCfg *countersConfiguration, bool isEventComplete);
|
||||
int sendPerfConfiguration(uint32_t count, uint32_t *pOffsets, uint32_t *pValues);
|
||||
uint32_t getCurrentReportId();
|
||||
bool isAvailable();
|
||||
uint32_t getReferenceNumber();
|
||||
|
||||
uint32_t getPerfCountersReferenceNumber() {
|
||||
mutex.lock();
|
||||
std::lock_guard<std::mutex> lg(mutex, std::adopt_lock);
|
||||
/////////////////////////////////////////////////////
|
||||
// Gpu oa/mmio configuration.
|
||||
/////////////////////////////////////////////////////
|
||||
virtual bool enableCountersConfiguration() = 0;
|
||||
virtual void releaseCountersConfiguration() = 0;
|
||||
|
||||
return refCounter;
|
||||
}
|
||||
//////////////////////////////////////////////////////
|
||||
// Gpu commands.
|
||||
//////////////////////////////////////////////////////
|
||||
uint32_t getGpuCommandsSize(const bool begin);
|
||||
bool getGpuCommands(TagNode<HwPerfCounter> &performanceCounters, const bool begin, const uint32_t bufferSize, void *pBuffer);
|
||||
|
||||
bool isAvailable() {
|
||||
return available;
|
||||
}
|
||||
/////////////////////////////////////////////////////
|
||||
// Gpu/Api reports.
|
||||
/////////////////////////////////////////////////////
|
||||
uint32_t getApiReportSize();
|
||||
uint32_t getGpuReportSize();
|
||||
bool getApiReport(const size_t inputParamSize, void *pClientData, size_t *pOutputSize, bool isEventComplete);
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// Metrics Library interface.
|
||||
/////////////////////////////////////////////////////
|
||||
MetricsLibrary *getMetricsLibraryInterface();
|
||||
void setMetricsLibraryInterface(std::unique_ptr<MetricsLibrary> newMetricsLibrary);
|
||||
bool openMetricsLibrary();
|
||||
void closeMetricsLibrary();
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// Metrics Library context/query handles.
|
||||
/////////////////////////////////////////////////////
|
||||
ContextHandle_1_0 getMetricsLibraryContext();
|
||||
QueryHandle_1_0 getQueryHandle();
|
||||
|
||||
protected:
|
||||
PerformanceCounters(OSTime *osTime);
|
||||
virtual bool verifyPmRegsCfg(InstrPmRegsCfg *pCfg, uint32_t *pLastPmRegsCfgHandle, bool *pLastPmRegsCfgPending);
|
||||
virtual void enableImpl();
|
||||
void shutdownImpl();
|
||||
MOCKABLE_VIRTUAL uint32_t getReportId() {
|
||||
return ++reportId & 0xFFF;
|
||||
}
|
||||
GFXCORE_FAMILY gfxFamily;
|
||||
InstrEscCbData cbData;
|
||||
OSInterface *osInterface;
|
||||
OSTime *osTime;
|
||||
bool hwMetricsEnabled;
|
||||
bool useMIRPC;
|
||||
void *pAutoSamplingInterface;
|
||||
uint64_t cpuRawTimestamp;
|
||||
/////////////////////////////////////////////////////
|
||||
// Common members.
|
||||
/////////////////////////////////////////////////////
|
||||
std::mutex mutex;
|
||||
uint32_t refCounter;
|
||||
bool available;
|
||||
uint32_t reportId;
|
||||
decltype(&instrAutoSamplingStart) autoSamplingStartFunc = instrAutoSamplingStart;
|
||||
decltype(&instrAutoSamplingStop) autoSamplingStopFunc = instrAutoSamplingStop;
|
||||
decltype(&instrCheckPmRegsCfg) checkPmRegsCfgFunc = instrCheckPmRegsCfg;
|
||||
decltype(&instrGetPerfCountersQueryData) getPerfCountersQueryDataFunc = instrGetPerfCountersQueryData;
|
||||
decltype(&instrEscGetPmRegsCfg) getPmRegsCfgFunc = instrEscGetPmRegsCfg;
|
||||
decltype(&instrEscHwMetricsEnable) hwMetricsEnableFunc = instrEscHwMetricsEnable;
|
||||
decltype(&instrEscLoadPmRegsCfg) loadPmRegsCfgFunc = instrEscLoadPmRegsCfg;
|
||||
decltype(&instrEscSetPmRegsCfg) setPmRegsCfgFunc = instrEscSetPmRegsCfg;
|
||||
decltype(&instrEscSendReadRegsCfg) sendReadRegsCfgFunc = instrEscSendReadRegsCfg;
|
||||
uint32_t referenceCounter = 0;
|
||||
bool available = false;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// Metrics Library interface.
|
||||
/////////////////////////////////////////////////////
|
||||
std::unique_ptr<MetricsLibrary> metricsLibrary = {};
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// Metrics Library client data.
|
||||
/////////////////////////////////////////////////////
|
||||
ClientData_1_0 clientData = {};
|
||||
ClientType_1_0 clientType = {ClientApi::OpenCL, ClientGen::Unknown};
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// Metrics Library context.
|
||||
/////////////////////////////////////////////////////
|
||||
ContextCreateData_1_0 contextData = {};
|
||||
ContextHandle_1_0 context = {};
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// Metrics Library oa/mmio counters configuration.
|
||||
/////////////////////////////////////////////////////
|
||||
ConfigurationHandle_1_0 oaConfiguration = {};
|
||||
ConfigurationHandle_1_0 userConfiguration = {};
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// Metrics Library query object.
|
||||
/////////////////////////////////////////////////////
|
||||
QueryHandle_1_0 query = {};
|
||||
};
|
||||
} // namespace NEO
|
||||
|
||||
@@ -36,6 +36,7 @@ set(RUNTIME_SRCS_OS_INTERFACE_WINDOWS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_library.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_library.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_memory_win.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_metrics_library.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_socket.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_thread_win.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_thread_win.h
|
||||
|
||||
@@ -22,10 +22,6 @@ OSInterface::~OSInterface() {
|
||||
delete osInterfaceImpl;
|
||||
}
|
||||
|
||||
uint32_t OSInterface::getHwContextId() const {
|
||||
return osInterfaceImpl->getHwContextId();
|
||||
}
|
||||
|
||||
uint32_t OSInterface::getDeviceHandle() const {
|
||||
return static_cast<uint32_t>(osInterfaceImpl->getDeviceHandle());
|
||||
}
|
||||
|
||||
55
runtime/os_interface/windows/os_metrics_library.cpp
Normal file
55
runtime/os_interface/windows/os_metrics_library.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2019 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "runtime/os_interface/metrics_library.h"
|
||||
|
||||
namespace NEO {
|
||||
//////////////////////////////////////////////////////
|
||||
// FUNCTION: MetricsLibrary::oaConfigurationActivate
|
||||
//////////////////////////////////////////////////////
|
||||
bool MetricsLibrary::oaConfigurationActivate(
|
||||
const ConfigurationHandle_1_0 &handle) {
|
||||
ConfigurationActivateData_1_0 data = {};
|
||||
data.Type = GpuConfigurationActivationType::EscapeCode;
|
||||
|
||||
return api->functions.ConfigurationActivate(
|
||||
handle,
|
||||
&data) == StatusCode::Success;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// FUNCTION: MetricsLibrary::oaConfigurationDeactivate
|
||||
//////////////////////////////////////////////////////
|
||||
bool MetricsLibrary::oaConfigurationDeactivate(
|
||||
const ConfigurationHandle_1_0 &handle) {
|
||||
return api->functions.ConfigurationDeactivate(
|
||||
handle) == StatusCode::Success;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// FUNCTION: MetricsLibrary::userConfigurationCreate
|
||||
//////////////////////////////////////////////////////
|
||||
bool MetricsLibrary::userConfigurationCreate(
|
||||
const ContextHandle_1_0 &context,
|
||||
ConfigurationHandle_1_0 &handle) {
|
||||
ConfigurationCreateData_1_0 data = {};
|
||||
data.HandleContext = context;
|
||||
data.Type = ObjectType::ConfigurationHwCountersUser;
|
||||
|
||||
return api->functions.ConfigurationCreate(
|
||||
&data,
|
||||
&handle) == StatusCode::Success;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// FUNCTION: MetricsLibrary::userConfigurationDelete
|
||||
//////////////////////////////////////////////////////
|
||||
bool MetricsLibrary::userConfigurationDelete(
|
||||
const ConfigurationHandle_1_0 &handle) {
|
||||
return api->functions.ConfigurationDelete(handle) == StatusCode::Success;
|
||||
}
|
||||
} // namespace NEO
|
||||
@@ -7,31 +7,82 @@
|
||||
|
||||
#include "performance_counters_win.h"
|
||||
|
||||
#include "runtime/device/device.h"
|
||||
#include "runtime/helpers/hw_helper.h"
|
||||
#include "runtime/os_interface/windows/os_interface.h"
|
||||
#include "runtime/os_interface/windows/windows_wrapper.h"
|
||||
#include "runtime/os_interface/windows/os_time_win.h"
|
||||
|
||||
namespace NEO {
|
||||
std::unique_ptr<PerformanceCounters> PerformanceCounters::create(OSTime *osTime) {
|
||||
return std::unique_ptr<PerformanceCounters>(new PerformanceCountersWin(osTime));
|
||||
}
|
||||
PerformanceCountersWin::PerformanceCountersWin(OSTime *osTime) : PerformanceCounters(osTime) {
|
||||
cbData.hAdapter = (void *)(UINT_PTR)osInterface->get()->getAdapterHandle();
|
||||
cbData.hDevice = (void *)(UINT_PTR)osInterface->get()->getDeviceHandle();
|
||||
cbData.pfnEscapeCb = osInterface->get()->getEscapeHandle();
|
||||
/////////////////////////////////////////////////////
|
||||
// PerformanceCounters::create
|
||||
/////////////////////////////////////////////////////
|
||||
std::unique_ptr<PerformanceCounters> PerformanceCounters::create(Device *device) {
|
||||
auto counter = std::make_unique<PerformanceCountersWin>();
|
||||
auto osInterface = device->getOSTime()->getOSInterface()->get();
|
||||
auto gen = device->getHardwareInfo().platform.eRenderCoreFamily;
|
||||
auto &hwHelper = HwHelper::get(gen);
|
||||
UNRECOVERABLE_IF(counter == nullptr);
|
||||
|
||||
counter->clientData.Windows.Adapter = reinterpret_cast<void *>(static_cast<UINT_PTR>(osInterface->getAdapterHandle()));
|
||||
counter->clientData.Windows.Device = reinterpret_cast<void *>(static_cast<UINT_PTR>(osInterface->getDeviceHandle()));
|
||||
counter->clientData.Windows.Device = reinterpret_cast<void *>(static_cast<UINT_PTR>(osInterface->getDeviceHandle()));
|
||||
counter->clientData.Windows.Escape = osInterface->getEscapeHandle();
|
||||
counter->clientData.Windows.KmdInstrumentationEnabled = device->getHardwareInfo().capabilityTable.instrumentationEnabled;
|
||||
counter->contextData.ClientData = &counter->clientData;
|
||||
counter->clientType.Gen = static_cast<MetricsLibraryApi::ClientGen>(hwHelper.getMetricsLibraryGenId());
|
||||
|
||||
return counter;
|
||||
}
|
||||
|
||||
PerformanceCountersWin::~PerformanceCountersWin() {
|
||||
if (pAutoSamplingInterface) {
|
||||
autoSamplingStopFunc(&pAutoSamplingInterface);
|
||||
pAutoSamplingInterface = nullptr;
|
||||
available = false;
|
||||
//////////////////////////////////////////////////////
|
||||
// PerformanceCountersWin::enableCountersConfiguration
|
||||
//////////////////////////////////////////////////////
|
||||
bool PerformanceCountersWin::enableCountersConfiguration() {
|
||||
// Release previous counters configuration so the user
|
||||
// can change configuration between kernels.
|
||||
releaseCountersConfiguration();
|
||||
|
||||
// Create mmio user configuration.
|
||||
if (!metricsLibrary->userConfigurationCreate(
|
||||
context,
|
||||
userConfiguration)) {
|
||||
DEBUG_BREAK_IF(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create oa configuration.
|
||||
if (!metricsLibrary->oaConfigurationCreate(
|
||||
context,
|
||||
oaConfiguration)) {
|
||||
DEBUG_BREAK_IF(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Enable oa configuration.
|
||||
if (!metricsLibrary->oaConfigurationActivate(
|
||||
oaConfiguration)) {
|
||||
DEBUG_BREAK_IF(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// PerformanceCountersWin::releaseCountersConfiguration
|
||||
//////////////////////////////////////////////////////
|
||||
void PerformanceCountersWin::releaseCountersConfiguration() {
|
||||
// Mmio user configuration.
|
||||
if (userConfiguration.IsValid()) {
|
||||
metricsLibrary->userConfigurationDelete(userConfiguration);
|
||||
userConfiguration.data = nullptr;
|
||||
}
|
||||
|
||||
// Oa configuration.
|
||||
if (oaConfiguration.IsValid()) {
|
||||
metricsLibrary->oaConfigurationDeactivate(oaConfiguration);
|
||||
metricsLibrary->oaConfigurationDelete(oaConfiguration);
|
||||
oaConfiguration.data = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void PerformanceCountersWin::initialize(const HardwareInfo *hwInfo) {
|
||||
PerformanceCounters::initialize(hwInfo);
|
||||
setAvailableFunc(true);
|
||||
verifyEnableFunc(cbData);
|
||||
}
|
||||
|
||||
} // namespace NEO
|
||||
|
||||
@@ -7,18 +7,18 @@
|
||||
|
||||
#pragma once
|
||||
#include "runtime/os_interface/performance_counters.h"
|
||||
#include "runtime/os_interface/windows/os_interface.h"
|
||||
|
||||
namespace NEO {
|
||||
|
||||
class PerformanceCountersWin : virtual public PerformanceCounters {
|
||||
public:
|
||||
PerformanceCountersWin(OSTime *osTime);
|
||||
~PerformanceCountersWin() override;
|
||||
void initialize(const HardwareInfo *hwInfo) override;
|
||||
PerformanceCountersWin() = default;
|
||||
~PerformanceCountersWin() override = default;
|
||||
|
||||
protected:
|
||||
decltype(&instrSetAvailable) setAvailableFunc = instrSetAvailable;
|
||||
decltype(&instrEscVerifyEnable) verifyEnableFunc = instrEscVerifyEnable;
|
||||
/////////////////////////////////////////////////////
|
||||
// Gpu oa/mmio configuration.
|
||||
/////////////////////////////////////////////////////
|
||||
bool enableCountersConfiguration() override;
|
||||
void releaseCountersConfiguration() override;
|
||||
};
|
||||
} // namespace NEO
|
||||
|
||||
Reference in New Issue
Block a user