Massive sunshine/viewer-dev catchup. Further implemented serverside baking and added/updated metrics feedback.
This commit is contained in:
327
indra/newview/llviewerassetstats.h
Normal file
327
indra/newview/llviewerassetstats.h
Normal file
@@ -0,0 +1,327 @@
|
||||
/**
|
||||
* @file llviewerassetstats.h
|
||||
* @brief Client-side collection of asset request statistics
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLVIEWERASSETSTATUS_H
|
||||
#define LL_LLVIEWERASSETSTATUS_H
|
||||
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llpointer.h"
|
||||
#include "llrefcount.h"
|
||||
#include "llviewerassettype.h"
|
||||
#include "llviewerassetstorage.h"
|
||||
#include "llsimplestat.h"
|
||||
#include "llsd.h"
|
||||
|
||||
/**
|
||||
* @class LLViewerAssetStats
|
||||
* @brief Records performance aspects of asset access operations.
|
||||
*
|
||||
* This facility is derived from a very similar simulator-based
|
||||
* one, LLSimAssetStats. It's function is to count asset access
|
||||
* operations and characterize response times. Collected data
|
||||
* are binned in several dimensions:
|
||||
*
|
||||
* - Asset types collapsed into a few aggregated categories
|
||||
* - By simulator UUID
|
||||
* - By transport mechanism (HTTP vs MessageSystem)
|
||||
* - By persistence (temp vs non-temp)
|
||||
*
|
||||
* Statistics collected are fairly basic at this point:
|
||||
*
|
||||
* - Counts of enqueue and dequeue operations
|
||||
* - Min/Max/Mean of asset transfer operations
|
||||
*
|
||||
* This collector differs from the simulator-based on in a
|
||||
* number of ways:
|
||||
*
|
||||
* - The front-end/back-end distinction doesn't exist in viewer
|
||||
* code
|
||||
* - Multiple threads must be safely accomodated in the viewer
|
||||
*
|
||||
* Access to results is by conversion to an LLSD with some standardized
|
||||
* key names. The intent of this structure is that it be emitted as
|
||||
* standard syslog-based metrics formatting where it can be picked
|
||||
* up by interested parties.
|
||||
*
|
||||
* For convenience, a set of free functions in namespace
|
||||
* LLViewerAssetStatsFF is provided for conditional test-and-call
|
||||
* operations.
|
||||
*/
|
||||
class LLViewerAssetStats
|
||||
{
|
||||
public:
|
||||
enum EViewerAssetCategories
|
||||
{
|
||||
EVACTextureTempHTTPGet, //< Texture GETs - temp/baked, HTTP
|
||||
EVACTextureTempUDPGet, //< Texture GETs - temp/baked, UDP
|
||||
EVACTextureNonTempHTTPGet, //< Texture GETs - perm, HTTP
|
||||
EVACTextureNonTempUDPGet, //< Texture GETs - perm, UDP
|
||||
EVACWearableUDPGet, //< Wearable GETs
|
||||
EVACSoundUDPGet, //< Sound GETs
|
||||
EVACGestureUDPGet, //< Gesture GETs
|
||||
EVACOtherGet, //< Other GETs
|
||||
|
||||
EVACCount // Must be last
|
||||
};
|
||||
|
||||
/**
|
||||
* Type for duration and other time values in the metrics. Selected
|
||||
* for compatibility with the pre-existing timestamp on the texture
|
||||
* fetcher class, LLTextureFetch.
|
||||
*/
|
||||
typedef U64 duration_t;
|
||||
|
||||
/**
|
||||
* Type for the region identifier used in stats. Currently uses
|
||||
* the region handle's type (a U64) rather than the regions's LLUUID
|
||||
* as the latter isn't available immediately.
|
||||
*/
|
||||
typedef U64 region_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Collected data for a single region visited by the avatar.
|
||||
*
|
||||
* Fairly simple, for each asset bin enumerated above a count
|
||||
* of enqueue and dequeue operations and simple stats on response
|
||||
* times for completed requests.
|
||||
*/
|
||||
class PerRegionStats : public LLRefCount
|
||||
{
|
||||
public:
|
||||
PerRegionStats(const region_handle_t region_handle)
|
||||
: LLRefCount(),
|
||||
mRegionHandle(region_handle)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
PerRegionStats(const PerRegionStats & src)
|
||||
: LLRefCount(),
|
||||
mRegionHandle(src.mRegionHandle),
|
||||
mTotalTime(src.mTotalTime),
|
||||
mStartTimestamp(src.mStartTimestamp),
|
||||
mFPS(src.mFPS)
|
||||
{
|
||||
for (int i = 0; i < LL_ARRAY_SIZE(mRequests); ++i)
|
||||
{
|
||||
mRequests[i] = src.mRequests[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Default assignment and destructor are correct.
|
||||
|
||||
void reset();
|
||||
|
||||
void merge(const PerRegionStats & src);
|
||||
|
||||
// Apply current running time to total and reset start point.
|
||||
// Return current timestamp as a convenience.
|
||||
void accumulateTime(duration_t now);
|
||||
|
||||
public:
|
||||
region_handle_t mRegionHandle;
|
||||
duration_t mTotalTime;
|
||||
duration_t mStartTimestamp;
|
||||
LLSimpleStatMMM<> mFPS;
|
||||
|
||||
struct prs_group
|
||||
{
|
||||
LLSimpleStatCounter mEnqueued;
|
||||
LLSimpleStatCounter mDequeued;
|
||||
LLSimpleStatMMM<duration_t> mResponse;
|
||||
}
|
||||
mRequests [EVACCount];
|
||||
};
|
||||
|
||||
public:
|
||||
LLViewerAssetStats();
|
||||
LLViewerAssetStats(const LLViewerAssetStats &);
|
||||
// Default destructor is correct.
|
||||
LLViewerAssetStats & operator=(const LLViewerAssetStats &); // Not defined
|
||||
|
||||
// Clear all metrics data. This leaves the currently-active region
|
||||
// in place but with zero'd data for all metrics. All other regions
|
||||
// are removed from the collection map.
|
||||
void reset();
|
||||
|
||||
// Set hidden region argument and establish context for subsequent
|
||||
// collection calls.
|
||||
void setRegion(region_handle_t region_handle);
|
||||
|
||||
// Asset GET Requests
|
||||
void recordGetEnqueued(LLViewerAssetType::EType at, bool with_http, bool is_temp);
|
||||
void recordGetDequeued(LLViewerAssetType::EType at, bool with_http, bool is_temp);
|
||||
void recordGetServiced(LLViewerAssetType::EType at, bool with_http, bool is_temp, duration_t duration);
|
||||
|
||||
// Frames-Per-Second Samples
|
||||
void recordFPS(F32 fps);
|
||||
|
||||
// Merge a source instance into a destination instance. This is
|
||||
// conceptually an 'operator+=()' method:
|
||||
// - counts are added
|
||||
// - minimums are min'd
|
||||
// - maximums are max'd
|
||||
// - other scalars are ignored ('this' wins)
|
||||
//
|
||||
void merge(const LLViewerAssetStats & src);
|
||||
|
||||
// Retrieve current metrics for all visited regions (NULL region UUID/handle excluded)
|
||||
// Returned LLSD is structured as follows:
|
||||
//
|
||||
// &stats_group = {
|
||||
// enqueued : int,
|
||||
// dequeued : int,
|
||||
// resp_count : int,
|
||||
// resp_min : float,
|
||||
// resp_max : float,
|
||||
// resp_mean : float
|
||||
// }
|
||||
//
|
||||
// &mmm_group = {
|
||||
// count : int,
|
||||
// min : float,
|
||||
// max : float,
|
||||
// mean : float
|
||||
// }
|
||||
//
|
||||
// {
|
||||
// duration: int
|
||||
// regions: {
|
||||
// $: { // Keys are strings of the region's handle in hex
|
||||
// duration: : int,
|
||||
// fps: : &mmm_group,
|
||||
// get_texture_temp_http : &stats_group,
|
||||
// get_texture_temp_udp : &stats_group,
|
||||
// get_texture_non_temp_http : &stats_group,
|
||||
// get_texture_non_temp_udp : &stats_group,
|
||||
// get_wearable_udp : &stats_group,
|
||||
// get_sound_udp : &stats_group,
|
||||
// get_gesture_udp : &stats_group,
|
||||
// get_other : &stats_group
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @param compact_output If true, omits from conversion any mmm_block
|
||||
// or stats_block that would contain all zero data.
|
||||
// Useful for transmission when the receiver knows
|
||||
// what is expected and will assume zero for missing
|
||||
// blocks.
|
||||
LLSD asLLSD(bool compact_output);
|
||||
|
||||
protected:
|
||||
typedef std::map<region_handle_t, LLPointer<PerRegionStats> > PerRegionContainer;
|
||||
|
||||
// Region of the currently-active region. Always valid but may
|
||||
// be zero after construction or when explicitly set. Unchanged
|
||||
// by a reset() call.
|
||||
region_handle_t mRegionHandle;
|
||||
|
||||
// Pointer to metrics collection for currently-active region. Always
|
||||
// valid and unchanged after reset() though contents will be changed.
|
||||
// Always points to a collection contained in mRegionStats.
|
||||
LLPointer<PerRegionStats> mCurRegionStats;
|
||||
|
||||
// Metrics data for all regions during one collection cycle
|
||||
PerRegionContainer mRegionStats;
|
||||
|
||||
// Time of last reset
|
||||
duration_t mResetTimestamp;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Global stats collectors one for each independent thread where
|
||||
* assets and other statistics are gathered. The globals are
|
||||
* expected to be created at startup time and then picked up by
|
||||
* their respective threads afterwards. A set of free functions
|
||||
* are provided to access methods behind the globals while both
|
||||
* minimally disrupting visual flow and supplying a description
|
||||
* of intent.
|
||||
*
|
||||
* Expected thread assignments:
|
||||
*
|
||||
* - Main: main() program execution thread
|
||||
* - Thread1: TextureFetch worker thread
|
||||
*/
|
||||
extern LLViewerAssetStats * gViewerAssetStatsMain;
|
||||
|
||||
extern LLViewerAssetStats * gViewerAssetStatsThread1;
|
||||
|
||||
namespace LLViewerAssetStatsFF
|
||||
{
|
||||
/**
|
||||
* @brief Allocation and deallocation of globals.
|
||||
*
|
||||
* init() should be called before threads are started that will access it though
|
||||
* you'll likely get away with calling it afterwards. cleanup() should only be
|
||||
* called after threads are shutdown to prevent races on the global pointers.
|
||||
*/
|
||||
void init();
|
||||
|
||||
void cleanup();
|
||||
|
||||
/**
|
||||
* We have many timers, clocks etc. in the runtime. This is the
|
||||
* canonical timestamp for these metrics which is compatible with
|
||||
* the pre-existing timestamping in the texture fetcher.
|
||||
*/
|
||||
inline LLViewerAssetStats::duration_t get_timestamp()
|
||||
{
|
||||
return LLTimer::getTotalTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Region context, event and duration loggers for the Main thread.
|
||||
*/
|
||||
void set_region_main(LLViewerAssetStats::region_handle_t region_handle);
|
||||
|
||||
void record_enqueue_main(LLViewerAssetType::EType at, bool with_http, bool is_temp);
|
||||
|
||||
void record_dequeue_main(LLViewerAssetType::EType at, bool with_http, bool is_temp);
|
||||
|
||||
void record_response_main(LLViewerAssetType::EType at, bool with_http, bool is_temp,
|
||||
LLViewerAssetStats::duration_t duration);
|
||||
|
||||
void record_fps_main(F32 fps);
|
||||
|
||||
/**
|
||||
* Region context, event and duration loggers for Thread 1.
|
||||
*/
|
||||
void set_region_thread1(LLViewerAssetStats::region_handle_t region_handle);
|
||||
|
||||
void record_enqueue_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp);
|
||||
|
||||
void record_dequeue_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp);
|
||||
|
||||
void record_response_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp,
|
||||
LLViewerAssetStats::duration_t duration);
|
||||
|
||||
} // namespace LLViewerAssetStatsFF
|
||||
|
||||
#endif // LL_LLVIEWERASSETSTATUS_H
|
||||
Reference in New Issue
Block a user