Files
UnrealEngineUWP/Engine/Source/Developer/Virtualization/Private/VirtualizationManager.cpp

838 lines
31 KiB
C++
Raw Normal View History

// Copyright Epic Games, Inc. All Rights Reserved.
#include "VirtualizationManager.h"
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
#include "HAL/PlatformTime.h"
#include "IVirtualizationBackend.h"
#include "Misc/CommandLine.h"
#include "Misc/ConfigCacheIni.h"
#include "Misc/CoreDelegates.h"
#include "Misc/PackageName.h"
#include "Misc/PackagePath.h"
#include "Misc/Parse.h"
#include "Misc/Paths.h"
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
#include "Misc/ScopeLock.h"
#include "ProfilingDebugging/CookStats.h"
#include "VirtualizationFilterSettings.h"
namespace UE::Virtualization
{
UE_REGISTER_VIRTUALIZATION_SYSTEM(UE::Virtualization::FVirtualizationManager, Default);
/** Utility struct, similar to FScopeLock but allows the lock to be enabled/disabled more easily */
struct FConditionalScopeLock
{
UE_NONCOPYABLE(FConditionalScopeLock);
FConditionalScopeLock(FCriticalSection* InSyncObject, bool bShouldLock)
{
checkf(InSyncObject != nullptr, TEXT("InSyncObject must point to a valid FCriticalSection"));
if (bShouldLock)
{
SyncObject = InSyncObject;
SyncObject->Lock();
}
else
{
SyncObject = nullptr;
}
}
/** Destructor that performs a release on the synchronization object. */
~FConditionalScopeLock()
{
if (SyncObject != nullptr)
{
SyncObject->Unlock();
}
}
private:
FCriticalSection* SyncObject;
};
/* Utility function for building up a lookup table of all available IBackendFactory interfaces*/
FVirtualizationManager::FRegistedFactories FindBackendFactories()
{
FVirtualizationManager::FRegistedFactories BackendFactories;
TArray<IVirtualizationBackendFactory*> FactoriesArray = IModularFeatures::Get().GetModularFeatureImplementations<IVirtualizationBackendFactory>(FName("VirtualizationBackendFactory"));
for (IVirtualizationBackendFactory* FactoryInterface : FactoriesArray)
{
checkf(FactoryInterface != nullptr, TEXT("A nullptr was added to the modular features for 'VirtualizationBackendFactory'"));
const FName FactoryName = FactoryInterface->GetName();
if (!BackendFactories.Contains(FactoryName))
{
BackendFactories.Add(FactoryName, FactoryInterface);
}
else
{
UE_LOG(LogVirtualization, Error, TEXT("Duplicate IBackendFactory found! Name '%s'"), *FactoryName.ToString());
}
}
return BackendFactories;
}
/* Utility function for finding entries in a given string*/
TArray<FString> ParseEntries(const FString& Data)
{
TArray<FString> Entries;
const TCHAR* DataPtr = *Data;
const TCHAR* EntryLabel = TEXT("Entry=");
const int32 EntryLabelLength = FCString::Strlen(EntryLabel);
FString ConfigEntryName;
while (FParse::Value(DataPtr, EntryLabel, ConfigEntryName))
{
Entries.Add(ConfigEntryName);
// Skip head so we can look for any additional entries (note that we might not skip past the existing
// entry has we have no idea how much whitespace was ignored by FParse, but it will be enough)
DataPtr += EntryLabelLength + ConfigEntryName.Len();
}
return Entries;
}
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
/**
* Profiling data allowing us to track how payloads are being push/pulled during the lifespan of the process. Note that as all backends are
* created at the same time, we don't need to add locked when accessing the maps. In addition FCookStats is thread safe when adding hits/misses
* so we don't have to worry about that either.
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
* We keep the FCookStats here rather than as a member of IVirtualizationBackend to try and avoid the backends needing to be aware of the data that
* we are gathering at all. This way all profiling code is kept to this cpp.
*/
namespace Profiling
{
#if ENABLE_COOK_STATS
TMap<FString, FCookStats::CallStats> CacheStats;
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
TMap<FString, FCookStats::CallStats> PushStats;
TMap<FString, FCookStats::CallStats> PullStats;
void CreateStats(const IVirtualizationBackend& Backend)
{
CacheStats.Add(Backend.GetDebugString());
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
PushStats.Add(Backend.GetDebugString());
PullStats.Add(Backend.GetDebugString());
}
FCookStats::CallStats& GetCacheStats(const IVirtualizationBackend& Backend)
{
return *CacheStats.Find(Backend.GetDebugString());
}
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
FCookStats::CallStats& GetPushStats(const IVirtualizationBackend& Backend)
{
return *PushStats.Find(Backend.GetDebugString());
}
FCookStats::CallStats& GetPullStats(const IVirtualizationBackend& Backend)
{
return *PullStats.Find(Backend.GetDebugString());
}
/** Returns true if we have gathered any profiling data at all */
bool HasProfilingData()
{
auto HasAccumulatedData = [](const TMap<FString, FCookStats::CallStats>& Stats)->bool
{
for (const auto& Iterator : Stats)
{
if (Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Counter) > 0)
{
return true;
}
if (Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Miss, FCookStats::CallStats::EStatType::Counter) > 0)
{
return true;
}
}
return false;
};
return HasAccumulatedData(CacheStats) || HasAccumulatedData(PushStats) || HasAccumulatedData(PullStats);
}
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
void LogStats()
{
if (!HasProfilingData())
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
{
return; // Early out if we have no data
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
}
UE_LOG(LogVirtualization, Log, TEXT(""));
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
UE_LOG(LogVirtualization, Log, TEXT("Virtualization ProfileData"));
UE_LOG(LogVirtualization, Log, TEXT("======================================================================================="));
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
if (CacheStats.Num() > 0)
{
UE_LOG(LogVirtualization, Log, TEXT("%-40s|%17s|%12s|%14s|"), TEXT("Caching Data"), TEXT("TotalSize (MB)"), TEXT("TotalTime(s)"), TEXT("DataRate(MB/S)"));
UE_LOG(LogVirtualization, Log, TEXT("----------------------------------------|-----------------|------------|--------------|"));
for (const auto& Iterator : CacheStats)
{
const double Time = Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Cycles) * FPlatformTime::GetSecondsPerCycle();
const int64 DataSizeMB = Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Bytes) / (1024 * 1024);
const double MBps = Time != 0.0 ? (DataSizeMB / Time) : 0.0;
UE_LOG(LogVirtualization, Log, TEXT("%-40.40s|%17" UINT64_FMT "|%12.3f|%14.3f|"),
*Iterator.Key,
DataSizeMB,
Time,
MBps);
}
UE_LOG(LogVirtualization, Log, TEXT("======================================================================================="));
}
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
if (PushStats.Num() > 0)
{
UE_LOG(LogVirtualization, Log, TEXT("%-40s|%17s|%12s|%14s|"), TEXT("Pushing Data"), TEXT("TotalSize (MB)"), TEXT("TotalTime(s)"), TEXT("DataRate(MB/S)"));
UE_LOG(LogVirtualization, Log, TEXT("----------------------------------------|-----------------|------------|--------------|"));
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
for (const auto& Iterator : PushStats)
{
const double Time = Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Cycles) * FPlatformTime::GetSecondsPerCycle();
const int64 DataSizeMB = Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Bytes) / (1024 * 1024);
const double MBps = Time != 0.0 ? (DataSizeMB / Time) : 0.0;
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
UE_LOG(LogVirtualization, Log, TEXT("%-40.40s|%17" UINT64_FMT "|%12.3f|%14.3f|"),
*Iterator.Key,
DataSizeMB,
Time,
MBps);
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
}
UE_LOG(LogVirtualization, Log, TEXT("======================================================================================="));
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
}
if (PullStats.Num() > 0)
{
UE_LOG(LogVirtualization, Log, TEXT("%-40s|%17s|%12s|%14s|"), TEXT("Pulling Data"), TEXT("TotalSize (MB)"), TEXT("TotalTime(s)"), TEXT("DataRate(MB/S)"));
UE_LOG(LogVirtualization, Log, TEXT("----------------------------------------|-----------------|------------|--------------|"));
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
for (const auto& Iterator : PullStats)
{
const double Time = Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Cycles) * FPlatformTime::GetSecondsPerCycle();
const int64 DataSizeMB = Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Bytes) / (1024 * 1024);
const double MBps = Time != 0.0 ? (DataSizeMB / Time) : 0.0;
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
UE_LOG(LogVirtualization, Log, TEXT("%-40.40s|%17" UINT64_FMT "|%12.3f|%14.3f|"),
*Iterator.Key,
DataSizeMB,
Time,
MBps);
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
}
UE_LOG(LogVirtualization, Log, TEXT("======================================================================================="));
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
}
}
#endif // ENABLE_COOK_STATS
} //namespace Profiling
FVirtualizationManager::FVirtualizationManager()
: bEnablePayloadPushing(true)
, bEnableCacheAfterPull(true)
, MinPayloadLength(0)
, BackendGraphName(TEXT("ContentVirtualizationBackendGraph_None"))
, bForceSingleThreaded(false)
, bFailPayloadPullOperations(false)
, bValidateAfterPushOperation(false)
{
UE_LOG(LogVirtualization, Log, TEXT("Virtualization manager created"));
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
// Allows us to log the profiling data on process exit.
// TODO: We should just be able to call the logging in the destructor, but
// we need to fix the startup/shutdown ordering of Mirage first.
COOK_STAT(FCoreDelegates::OnExit.AddStatic(Profiling::LogStats));
FConfigFile PlatformEngineIni;
if (FConfigCacheIni::LoadLocalIniFile(PlatformEngineIni, TEXT("Engine"), true))
{
ApplySettingsFromConfigFiles(PlatformEngineIni);
ApplyDebugSettingsFromConfigFiles(PlatformEngineIni);
}
else
{
UE_LOG(LogVirtualization, Error, TEXT("Failed to load config file settings for content virtualization"));
}
ApplySettingsFromCmdline();
MountBackends();
}
FVirtualizationManager::~FVirtualizationManager()
{
UE_LOG(LogVirtualization, Log, TEXT("Destroying backends"));
LocalCachableBackends.Empty();
PersistentStorageBackends.Empty();
PullEnabledBackends.Empty();
AllBackends.Empty(); // This will delete all backends and beyond this point all references to them are invalid
UE_LOG(LogVirtualization, Log, TEXT("Virtualization manager destroyed"));
}
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
bool FVirtualizationManager::IsEnabled() const
{
return !AllBackends.IsEmpty();
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
}
bool FVirtualizationManager::PushData(const FPayloadId& Id, const FCompressedBuffer& Payload, EStorageType StorageType, const FPackagePath& PackageContext)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FVirtualizationManager::PushData);
if (!Id.IsValid())
{
// TODO: Should an invalid FPayloadId be an expected input, if so demote this from Warning->Verbose
UE_LOG(LogVirtualization, Warning, TEXT("Attempting to push a virtualized payload with an invalid FPayloadId"));
return false;
}
FConditionalScopeLock _(&ForceSingleThreadedCS, bForceSingleThreaded);
// Early out if there are no backends or if the pushing of payloads has been disabled
if (!IsEnabled() || bEnablePayloadPushing == false)
{
return false;
}
// Early out if we have no payload
if (Payload.GetCompressedSize() == 0)
{
// TODO: Should an invalid payload be an expected input, if so demote this from Warning->Verbose
UE_LOG(LogVirtualization, Warning, TEXT("Attempting to push an invalid virtualized payload (id: %s)"), *Id.ToString());
return false;
}
// Early out if the payload length is below our minimum required length
if ((int64)Payload.GetCompressedSize() < MinPayloadLength)
{
UE_LOG( LogVirtualization,
Verbose,
TEXT("Attempting to push a virtualized payload (id: %s) that is smaller (%" UINT64_FMT ") than the MinPayloadLength (%" INT64_FMT ")"),
*Id.ToString(), Payload.GetCompressedSize(), MinPayloadLength);
return false;
}
if (!ShouldVirtualizePackage(PackageContext))
{
UE_LOG( LogVirtualization, Verbose, TEXT("Payload '%s' for package '%s' will not be virtualized due to filtering"),
*Id.ToString(), *PackageContext.GetDebugName());
return false;
}
// TODO: Note that all push operations are currently synchronous, probably
// should change to async at some point, although this makes handling failed
// pushed much more difficult.
int32 ErrorCount = 0;
bool bWasPayloadPushed = false;
FBackendArray& Backends = StorageType == EStorageType::Local ? LocalCachableBackends : PersistentStorageBackends;
for (IVirtualizationBackend* Backend : Backends)
{
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
const EPushResult Result = TryPushDataToBackend(*Backend, Id, Payload) ? EPushResult::Success : EPushResult::Failed;
UE_CLOG(Result != EPushResult::Failed, LogVirtualization, Verbose, TEXT("[%s] Pushed the payload '%s'"), *Backend->GetDebugString(), *Id.ToString());
UE_CLOG(Result == EPushResult::Failed, LogVirtualization, Error, TEXT("[%s] Failed to push the payload '%s'"), *Backend->GetDebugString(), *Id.ToString());
if (Result == EPushResult::Failed)
{
ErrorCount++;
}
// Debugging operation where we immediately try to pull the payload after each push (when possible) and assert
// that the pulled payload is the same as the original
if (bValidateAfterPushOperation && Result != EPushResult::Failed && Backend->SupportsPullOperations())
{
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
FCompressedBuffer PulledPayload = PullDataFromBackend(*Backend, Id);
checkf(Payload.GetRawHash() == PulledPayload.GetRawHash(), TEXT("[%s] Failed to pull payload '%s' after it was pushed to backend"),
*Backend->GetDebugString(), *Id.ToString());
}
}
UE_CLOG(ErrorCount == Backends.Num(), LogVirtualization, Error, TEXT("Payload '%s' failed to be pushed to any backend'"), *Id.ToString());
// For local storage we consider the push to have failed only if ALL backends gave an error, if at least one backend succeeded then the operation succeeded.
// For persistent storage we require that all backends succeeded, so any errors will fail the push operation.
return StorageType == EStorageType::Local ? ErrorCount < Backends.Num() : ErrorCount == 0;
}
FCompressedBuffer FVirtualizationManager::PullData(const FPayloadId& Id)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FVirtualizationManager::PullData);
if (!Id.IsValid())
{
// TODO: See below, should errors here be fatal?
UE_LOG(LogVirtualization, Error, TEXT("Attempting to pull a virtualized payload with an invalid FPayloadId"));
return FCompressedBuffer();
}
if (PullEnabledBackends.IsEmpty())
{
// TODO: See below, should errors here be fatal?
UE_LOG(LogVirtualization, Error, TEXT("Payload '%s' failed to be pulled as there are no backends mounted!'"), *Id.ToString());
return FCompressedBuffer();
}
if (bFailPayloadPullOperations)
{
UE_LOG(LogVirtualization, Error, TEXT("Payload '%s' failed to be pulled as the debug option 'FailPayloadPullOperations' is enabled!"), *Id.ToString());
return FCompressedBuffer();
}
FConditionalScopeLock _(&ForceSingleThreadedCS, bForceSingleThreaded);
for (IVirtualizationBackend* Backend : PullEnabledBackends)
{
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
FCompressedBuffer Payload = PullDataFromBackend(*Backend, Id);
if (Payload)
{
if (bEnableCacheAfterPull)
{
CachePayload(Id, Payload, Backend);
}
return Payload;
}
}
// TODO: Maybe this should be a fatal error? If we keep it as an error we need to make sure any calling
// code handles it properly.
// Could be worth extending ::PullData to return error codes instead so we can make a better distinction
// between the payload not being found in any of the backends and one or more of the backends failing.
UE_LOG(LogVirtualization, Error, TEXT("Payload '%s' failed to be pulled from any backend'"), *Id.ToString());
return FCompressedBuffer();
}
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
FPayloadActivityInfo FVirtualizationManager::GetPayloadActivityInfo() const
{
FPayloadActivityInfo Info;
#if ENABLE_COOK_STATS
for (const auto& Iterator : Profiling::CacheStats)
{
Info.Cache.PayloadCount += Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Counter);
Info.Cache.TotalBytes += Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Bytes);
Info.Cache.CyclesSpent += Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Cycles);
}
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
for (const auto& Iterator : Profiling::PushStats)
{
Info.Push.PayloadCount += Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Counter);
Info.Push.TotalBytes += Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Bytes);
Info.Push.CyclesSpent += Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Cycles);
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
}
for (const auto& Iterator : Profiling::PullStats)
{
Info.Pull.PayloadCount += Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Counter);
Info.Pull.TotalBytes += Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Bytes);
Info.Pull.CyclesSpent += Iterator.Value.GetAccumulatedValueAnyThread(FCookStats::CallStats::EHitOrMiss::Hit, FCookStats::CallStats::EStatType::Cycles);
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
}
#endif // ENABLE_COOK_STATS
return Info;
}
void FVirtualizationManager::ApplySettingsFromConfigFiles(const FConfigFile& PlatformEngineIni)
{
UE_LOG(LogVirtualization, Log, TEXT("Loading virtualization manager settings from config files..."));
bool bEnablePayloadPushingFromIni = false;
if (PlatformEngineIni.GetBool(TEXT("Core.ContentVirtualization"), TEXT("EnablePushToBackend"), bEnablePayloadPushingFromIni))
{
bEnablePayloadPushing = bEnablePayloadPushingFromIni;
UE_LOG(LogVirtualization, Log, TEXT("\tEnablePushToBackend : %s"), bEnablePayloadPushing ? TEXT("true") : TEXT("false") );
}
else
{
UE_LOG(LogVirtualization, Error, TEXT("Failed to load [Core.ContentVirtualization].EnablePushToBackend from config file!"));
}
bool bEnableCacheAfterPullFromIni = false;
if (PlatformEngineIni.GetBool(TEXT("Core.ContentVirtualization"), TEXT("EnableCacheAfterPull"), bEnableCacheAfterPullFromIni))
{
bEnableCacheAfterPull = bEnableCacheAfterPullFromIni;
UE_LOG(LogVirtualization, Log, TEXT("\tCachePulledPayloads : %s"), bEnableCacheAfterPull ? TEXT("true") : TEXT("false"));
}
else
{
UE_LOG(LogVirtualization, Error, TEXT("Failed to load [Core.ContentVirtualization].EnableCacheAfterPull from config file!"));
}
int64 MinPayloadLengthFromIni = 0;
if (PlatformEngineIni.GetInt64(TEXT("Core.ContentVirtualization"), TEXT("MinPayloadLength"), MinPayloadLengthFromIni))
{
MinPayloadLength = MinPayloadLengthFromIni;
UE_LOG(LogVirtualization, Log, TEXT("\tMinPayloadLength : %" INT64_FMT), MinPayloadLength );
}
else
{
UE_LOG(LogVirtualization, Error, TEXT("Failed to load [Core.ContentVirtualization].MinPayloadLength from config file!"));;
}
FString BackendGraphNameFromIni;
if (PlatformEngineIni.GetString(TEXT("Core.ContentVirtualization"), TEXT("BackendGraph"), BackendGraphNameFromIni))
{
BackendGraphName = BackendGraphNameFromIni;
UE_LOG(LogVirtualization, Log, TEXT("\tBackendGraphName : %s"), *BackendGraphName );
}
else
{
UE_LOG(LogVirtualization, Error, TEXT("Failed to load [Core.ContentVirtualization].BackendGraph from config file!"));;
}
bool bFilterEngineContentFromIni = true;
if (PlatformEngineIni.GetBool(TEXT("Core.ContentVirtualization"), TEXT("FilterEngineContent"), bFilterEngineContentFromIni))
{
bFilterEngineContent = bFilterEngineContentFromIni;
UE_LOG(LogVirtualization, Log, TEXT("\tFilterEngineContent : %s"), bFilterEngineContent ? TEXT("true") : TEXT("false"));
}
else
{
UE_LOG(LogVirtualization, Error, TEXT("Failed to load [Core.ContentVirtualization].FilterEngineContent from config file!"));
}
bool bFilterEnginePluginContentFromIni = true;
if (PlatformEngineIni.GetBool(TEXT("Core.ContentVirtualization"), TEXT("FilterEnginePluginContent"), bFilterEnginePluginContentFromIni))
{
bFilterEnginePluginContent = bFilterEnginePluginContentFromIni;
UE_LOG(LogVirtualization, Log, TEXT("\tFilterEnginePluginContent : %s"), bFilterEnginePluginContent ? TEXT("true") : TEXT("false"));
}
else
{
UE_LOG(LogVirtualization, Error, TEXT("Failed to load [Core.ContentVirtualization].FilterEnginePluginContent from config file!"));
}
}
void FVirtualizationManager::ApplySettingsFromCmdline()
{
FString CmdlineGraphName;
if (FParse::Value(FCommandLine::Get(), TEXT("-BackendGraph="), CmdlineGraphName))
{
UE_LOG(LogVirtualization, Log, TEXT("Backend graph overriden from the cmdline: '%s'"), *CmdlineGraphName);
BackendGraphName = CmdlineGraphName;
}
if (FParse::Param(FCommandLine::Get(), TEXT("VirtualizationForceSingleThreaded")))
{
bForceSingleThreaded = true;
UE_LOG(LogVirtualization, Log, TEXT("ForceSingleThreaded overriden from the cmdline: true"));
}
}
void FVirtualizationManager::ApplyDebugSettingsFromConfigFiles(const FConfigFile& PlatformEngineIni)
{
UE_LOG(LogVirtualization, Log, TEXT("Loading virtualization manager debugging settings from config files..."));
// Note that the debug settings are optional and could be left out of the config files entirely
bool bForceSingleThreadedFromIni = false;
if (PlatformEngineIni.GetBool(TEXT("Core.ContentVirtualizationDebugOptions"), TEXT("ForceSingleThreaded"), bForceSingleThreadedFromIni))
{
bForceSingleThreaded = bForceSingleThreadedFromIni;
UE_LOG(LogVirtualization, Log, TEXT("\tForceSingleThreaded : %s"), bForceSingleThreaded ? TEXT("true") : TEXT("false"));
}
bool bFailPayloadPullOperationsFromIni = false;
if (PlatformEngineIni.GetBool(TEXT("Core.ContentVirtualizationDebugOptions"), TEXT("FailPayloadPullOperations"), bFailPayloadPullOperationsFromIni))
{
bFailPayloadPullOperations = bFailPayloadPullOperationsFromIni;
UE_LOG(LogVirtualization, Log, TEXT("\tFailPayloadPullOperations : %s"), bFailPayloadPullOperations ? TEXT("true") : TEXT("false"));
}
bool bValidateAfterPushOperationFromIni = false;
if (PlatformEngineIni.GetBool(TEXT("Core.ContentVirtualizationDebugOptions"), TEXT("ValidateAfterPushOperation"), bValidateAfterPushOperationFromIni))
{
bValidateAfterPushOperation = bValidateAfterPushOperationFromIni;
UE_LOG(LogVirtualization, Log, TEXT("ValidateAfterPushOperation : %s"), bValidateAfterPushOperation ? TEXT("true") : TEXT("false"));
}
// Some debug options will cause intentional breaks or slow downs for testing purposes, if these are enabled then we should give warning/errors
// so it is clear in the log that future failures are being caused by the given dev option.
UE_CLOG(bForceSingleThreaded, LogVirtualization, Warning, TEXT("ForceSingleThreaded is enabled, virtualization will run in single threaded mode and may be slower!"));
UE_CLOG(bFailPayloadPullOperations, LogVirtualization, Error, TEXT("FailPayloadPullOperations is enabled, all virtualization pull operations will fail!"));
UE_CLOG(bValidateAfterPushOperation, LogVirtualization, Error, TEXT("ValidateAfterPushOperation is enabled, each push will be followed by a pull to validate it!"));
}
void FVirtualizationManager::MountBackends()
{
UE_LOG(LogVirtualization, Log, TEXT("Mounting virtualization backends..."));
const FRegistedFactories FactoryLookupTable = FindBackendFactories();
UE_LOG(LogVirtualization, Verbose, TEXT("Found %d backend factories"), FactoryLookupTable.Num());
const TCHAR* GraphName = *BackendGraphName;
if(!GConfig->DoesSectionExist(GraphName, GEngineIni))
{
UE_LOG(LogVirtualization, Fatal, TEXT("Unable to find the backend graph: '%s' [ini=%s]."), GraphName, *GEngineIni);
}
UE_LOG(LogVirtualization, Log, TEXT("Using backend graph: '%s'"), GraphName);
// It is important to parse the local storage hierarchy first so those backends will show up before the
// persistent storage backends in 'PullEnabledBackends'.
ParseHierarchy(GraphName, TEXT("LocalStorageHierarchy"), FactoryLookupTable, LocalCachableBackends);
ParseHierarchy(GraphName, TEXT("PersistentStorageHierarchy"), FactoryLookupTable, PersistentStorageBackends);
}
void FVirtualizationManager::ParseHierarchy(const TCHAR* GraphName, const TCHAR* HierarchyKey, const FRegistedFactories& FactoryLookupTable, FBackendArray& PushArray)
{
FString HierarchyData;
if (!GConfig->GetString(GraphName, HierarchyKey, HierarchyData, GEngineIni))
{
UE_LOG(LogVirtualization, Fatal, TEXT("Unable to find the '%s' entry for the content virtualization backend graph '%s' [ini=%s]."), HierarchyKey, GraphName, *GEngineIni);
}
if (HierarchyData.IsEmpty())
{
UE_LOG(LogVirtualization, Fatal, TEXT("The '%s' entry for backend graph '%s' is empty [ini=%s]."), HierarchyKey, GraphName, *GEngineIni);
}
TArray<FString> Entries = ParseEntries(HierarchyData);
UE_LOG(LogVirtualization, Log, TEXT("The backend graph hierarchy '%s' has %d entries"), HierarchyKey, Entries.Num());
for (const FString& Entry : Entries)
{
CreateBackend(GraphName, Entry, FactoryLookupTable, PushArray);
}
}
bool FVirtualizationManager::CreateBackend(const TCHAR* GraphName, const FString& ConfigEntryName, const FRegistedFactories& FactoryLookupTable, FBackendArray& PushArray)
{
// All failures in this method are considered fatal, however it still returns true/false in case we decide
// to be more forgiving in the future.
UE_LOG(LogVirtualization, Log, TEXT("Attempting to create back end entry '%s'"), *ConfigEntryName);
FString BackendData;
if (!GConfig->GetString(GraphName, *ConfigEntryName, BackendData, GEngineIni))
{
UE_LOG(LogVirtualization, Fatal, TEXT("Unable to find the entry '%s' in the content virtualization backend graph '%s' [ini=%s]."), *ConfigEntryName, GraphName, *GEngineIni);
return false;
}
FString BackendType;
if (FParse::Value(*BackendData, TEXT("Type="), BackendType) && !BackendType.IsEmpty())
{
// Put the rest of the ini file entry into a string to pass to the backend.
FString Cmdine = BackendData.RightChop(BackendData.Find(BackendType) + BackendType.Len());
Cmdine.RemoveFromEnd(TEXT(")"));
UE::Virtualization::IVirtualizationBackendFactory* const* FactoryPtr = FactoryLookupTable.Find(FName(BackendType));
if (FactoryPtr != nullptr && *FactoryPtr != nullptr)
{
IVirtualizationBackendFactory* Factory = *FactoryPtr;
TUniquePtr<IVirtualizationBackend> Backend = Factory->CreateInstance(ConfigEntryName);
if (Backend == nullptr)
{
UE_LOG(LogVirtualization, Fatal, TEXT("IVirtualizationBackendFactory '%s' failed to create an instance!"), *Factory->GetName().ToString());
return false;
}
if (Backend->Initialize(Cmdine))
{
AddBackend(MoveTemp(Backend), PushArray);
}
else
{
UE_LOG(LogVirtualization, Fatal, TEXT("Backend '%s' reported errors when initializing"), *ConfigEntryName);
return false;
}
}
else
{
UE_LOG(LogVirtualization, Fatal, TEXT("No backend factory found that can create the type '%s'"), *BackendType);
return false;
}
}
else
{
UE_LOG(LogVirtualization, Fatal, TEXT("No 'Type=' entry found for '%s' in the config file"), *ConfigEntryName);
return false;
}
return true;
}
void FVirtualizationManager::AddBackend(TUniquePtr<IVirtualizationBackend> Backend, FBackendArray& PushArray)
{
checkf(!AllBackends.Contains(Backend), TEXT("Adding the same virtualization backend (%s) multiple times!"), *Backend->GetDebugString());
// Move ownership of the backend to AllBackends
AllBackends.Add(MoveTemp(Backend));
// Get a reference pointer to use in the other backend arrays
IVirtualizationBackend* BackendRef = AllBackends.Last().Get();
if (BackendRef->SupportsPullOperations())
{
PullEnabledBackends.Add(BackendRef);
}
if (BackendRef->SupportsPushOperations())
{
PushArray.Add(BackendRef);
}
COOK_STAT(Profiling::CreateStats(*BackendRef));
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
UE_LOG(LogVirtualization, Log, TEXT("Mounted backend: %s"), *BackendRef->GetDebugString());
}
void FVirtualizationManager::CachePayload(const FPayloadId& Id, const FCompressedBuffer& Payload, const IVirtualizationBackend* BackendSource)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FVirtualizationManager::CachePayload);
// We start caching at the first (assumed to be fastest) local cache backend.
for (IVirtualizationBackend* BackendToCache : LocalCachableBackends)
{
if (BackendToCache == BackendSource)
{
return; // No point going past BackendSource
}
bool bResult = TryCacheDataToBackend(*BackendToCache, Id, Payload);
UE_CLOG( !bResult, LogVirtualization, Warning,
TEXT("Failed to cache payload '%s' to backend '%s'"),
*Id.ToString(),
*BackendToCache->GetDebugString());
// Debugging operation where we immediately try to pull the payload after each push (when possible) and assert
// that the pulled payload is the same as the original
if (bValidateAfterPushOperation && bResult && BackendToCache->SupportsPullOperations())
{
FCompressedBuffer PulledPayload = PullDataFromBackend(*BackendToCache, Id);
checkf(Payload.GetRawHash() == PulledPayload.GetRawHash(), TEXT("[%s] Failed to pull payload '%s' after it was cached to backend"),
*BackendToCache->GetDebugString(), *Id.ToString());
}
}
}
bool FVirtualizationManager::TryCacheDataToBackend(IVirtualizationBackend& Backend, const FPayloadId& Id, const FCompressedBuffer& Payload)
{
COOK_STAT(FCookStats::FScopedStatsCounter Timer(Profiling::GetCacheStats(Backend)));
const EPushResult Result = Backend.PushData(Id, Payload);
if (Result == EPushResult::Success)
{
COOK_STAT(Timer.AddHit(Payload.GetCompressedSize()));
}
return Result != EPushResult::Failed;
}
Add some basic profile data to Mirage to make it easier for people to see when payloads are being pushed to or pulled from the various backends. #rb Per.Larsson #rnx * VirtualizationManager - Add method ::IsEnabled which allows the caller to poll if content virtualization is enabled or not. - Add method ::GetPayloadActivityInfo to return profiling data - Added a new Profiling namespace containing all of the profiling code. -- The idea is to try and keep all profiling data contained in the virtualization manager and not require the backends to be aware of it. - The actual pull/push operations have been moved to new private methods ::TryPushDataToBackend and ::PullDataFromBackend, by limiting the scolpe of where the actual operation occur makes it easier to add the profiling code. - We use the cooking stats system for recording our profiling data. Currently this adds no real value and we could've implemented our own but longer term this code might get hooked into FCookStatsManager:: CookStatsCallbacks to add it to our telemetry systems and this will be easier to do if it is already in the cooking stats formats. * SVirtualizationStaticIndicator - The widget is based on SDDCStatusIndicator for the DDC and is placed just before it in the UI. - The widget will only be shown if the content virtualization system is enabled, so functions as an easy way to check that (maybe in the future it can be on all the time in which case we'd need the widget to reflect when the systems are disabled) - Currently shows a green down arrow when a payload has been pulled and a green up arrow when a payload has been pushed. - The tool tip shown on mouse over will show the total data sizes pulled and pushed from the backends. #preflight 60b87c34ae46a100017d5334 [CL 16544645 by paul chipchase in ue5-main branch]
2021-06-03 04:35:17 -04:00
bool FVirtualizationManager::TryPushDataToBackend(IVirtualizationBackend& Backend, const FPayloadId& Id, const FCompressedBuffer& Payload)
{
COOK_STAT(FCookStats::FScopedStatsCounter Timer(Profiling::GetPushStats(Backend)));
const EPushResult Result = Backend.PushData(Id, Payload);
if (Result == EPushResult::Success)
{
COOK_STAT(Timer.AddHit(Payload.GetCompressedSize()));
}
return Result != EPushResult::Failed;
}
FCompressedBuffer FVirtualizationManager::PullDataFromBackend(IVirtualizationBackend& Backend, const FPayloadId& Id)
{
COOK_STAT(FCookStats::FScopedStatsCounter Timer(Profiling::GetPullStats(Backend)));
FCompressedBuffer Payload = Backend.PullData(Id);
if (!Payload.IsNull())
{
COOK_STAT(Timer.AddHit(Payload.GetCompressedSize()));
}
return Payload;
}
bool FVirtualizationManager::ShouldVirtualizePackage(const FPackagePath& PackagePath) const
{
TRACE_CPUPROFILER_EVENT_SCOPE(FVirtualizationManager::ShouldVirtualizePackage);
// We require a valid mounted path for filtering
if (!PackagePath.IsMountedPath())
{
return true;
}
TStringBuilder<256> PackageName;
PackagePath.AppendPackageName(PackageName);
TStringBuilder<64> MountPointName;
TStringBuilder<256> MountPointPath;
TStringBuilder<256> RelativePath;
if (!FPackageName::TryGetMountPointForPath(PackageName, MountPointName, MountPointPath, RelativePath))
{
return true;
}
if (bFilterEngineContent)
{
// Do not virtualize engine content
if (MountPointName.ToView() == TEXT("/Engine/"))
{
return false;
}
}
if (bFilterEnginePluginContent)
{
// Do not virtualize engine plugin content
if (FPaths::IsUnderDirectory(MountPointPath.ToString(), FPaths::EnginePluginsDir()))
{
return false;
}
}
const UVirtualizationFilterSettings* Settings = GetDefault<UVirtualizationFilterSettings>();
if (Settings != nullptr)
{
const FStringView PackageNameView = PackageName.ToView();
for (const FString& Exclusion : Settings->ExcludePackagePaths)
{
if (Exclusion.EndsWith(TEXT("/")))
{
// Directory path, exclude everything under it
if (PackageNameView.StartsWith(Exclusion))
{
return false;
}
}
else
{
// Path to an asset, exclude if it matches exactly
if (PackageNameView == Exclusion)
{
return false;
}
}
}
}
return true;
}
} // namespace UE::Virtualization