mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-10 04:53:04 +02:00
add a new SimpleMovingAverage class, replaces CounterStats
This commit is contained in:
parent
651f7434a8
commit
b9a1faf284
9 changed files with 116 additions and 267 deletions
|
@ -93,24 +93,24 @@ long int VoxelSystem::getVoxelsCreated() {
|
|||
return tree->voxelsCreated;
|
||||
}
|
||||
|
||||
long int VoxelSystem::getVoxelsCreatedRunningAverage() {
|
||||
return tree->voxelsCreatedStats.getRunningAverage();
|
||||
float VoxelSystem::getVoxelsCreatedPerSecondAverage() {
|
||||
return (1 / tree->voxelsCreatedStats.getEventDeltaAverage());
|
||||
}
|
||||
|
||||
long int VoxelSystem::getVoxelsColored() {
|
||||
return tree->voxelsColored;
|
||||
}
|
||||
|
||||
long int VoxelSystem::getVoxelsColoredRunningAverage() {
|
||||
return tree->voxelsColoredStats.getRunningAverage();
|
||||
float VoxelSystem::getVoxelsColoredPerSecondAverage() {
|
||||
return tree->voxelsColoredStats.getEventDeltaAverage();
|
||||
}
|
||||
|
||||
long int VoxelSystem::getVoxelsBytesRead() {
|
||||
return tree->voxelsBytesRead;
|
||||
}
|
||||
|
||||
long int VoxelSystem::getVoxelsBytesReadRunningAverage() {
|
||||
return tree->voxelsBytesReadStats.getRunningAverage();
|
||||
float VoxelSystem::getVoxelsBytesReadAverage() {
|
||||
return tree->voxelsBytesReadStats.getAverage();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -40,9 +40,9 @@ public:
|
|||
long int getVoxelsCreated();
|
||||
long int getVoxelsColored();
|
||||
long int getVoxelsBytesRead();
|
||||
long int getVoxelsCreatedRunningAverage();
|
||||
long int getVoxelsColoredRunningAverage();
|
||||
long int getVoxelsBytesReadRunningAverage();
|
||||
float getVoxelsCreatedPerSecondAverage();
|
||||
float getVoxelsColoredPerSecondAverage();
|
||||
float getVoxelsBytesReadAverage();
|
||||
|
||||
private:
|
||||
int voxelsRendered;
|
||||
|
|
|
@ -74,10 +74,11 @@
|
|||
#include "Oscilloscope.h"
|
||||
#include "UDPSocket.h"
|
||||
#include "SerialInterface.h"
|
||||
#include <PerfStat.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <AvatarData.h>
|
||||
#include <PerfStat.h>
|
||||
#include <SimpleMovingAverage.h>
|
||||
|
||||
#include "ViewFrustum.h"
|
||||
|
||||
|
@ -235,35 +236,6 @@ void displayStats(void)
|
|||
sprintf(stats, "FPS = %3.0f Pkts/s = %d Bytes/s = %d Head(x,y,z)= %4.2f, %4.2f, %4.2f ",
|
||||
FPS, packetsPerSecond, bytesPerSecond, avatarPos.x,avatarPos.y,avatarPos.z);
|
||||
drawtext(10, statsVerticalOffset + 49, 0.10f, 0, 1.0, 0, stats);
|
||||
|
||||
std::stringstream voxelStats;
|
||||
voxelStats << "Voxels Rendered: " << voxels.getVoxelsRendered();
|
||||
drawtext(10, statsVerticalOffset + 70, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str());
|
||||
|
||||
voxelStats.str("");
|
||||
voxelStats << "Voxels Created: " << voxels.getVoxelsCreated() << " (" << voxels.getVoxelsCreatedRunningAverage()
|
||||
<< "/sec in last "<< COUNTETSTATS_TIME_FRAME << " seconds) ";
|
||||
drawtext(10, statsVerticalOffset + 250, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str());
|
||||
|
||||
voxelStats.str("");
|
||||
voxelStats << "Voxels Colored: " << voxels.getVoxelsColored() << " (" << voxels.getVoxelsColoredRunningAverage()
|
||||
<< "/sec in last "<< COUNTETSTATS_TIME_FRAME << " seconds) ";
|
||||
drawtext(10, statsVerticalOffset + 270, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str());
|
||||
|
||||
voxelStats.str("");
|
||||
voxelStats << "Voxels Bytes Read: " << voxels.getVoxelsBytesRead()
|
||||
<< " (" << voxels.getVoxelsBytesReadRunningAverage() << "/sec in last "<< COUNTETSTATS_TIME_FRAME << " seconds) ";
|
||||
drawtext(10, statsVerticalOffset + 290,0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str());
|
||||
|
||||
voxelStats.str("");
|
||||
long int voxelsBytesPerColored = voxels.getVoxelsColored() ? voxels.getVoxelsBytesRead()/voxels.getVoxelsColored() : 0;
|
||||
long int voxelsBytesPerColoredAvg = voxels.getVoxelsColoredRunningAverage() ?
|
||||
voxels.getVoxelsBytesReadRunningAverage()/voxels.getVoxelsColoredRunningAverage() : 0;
|
||||
|
||||
voxelStats << "Voxels Bytes per Colored: " << voxelsBytesPerColored
|
||||
<< " (" << voxelsBytesPerColoredAvg << "/sec in last "<< COUNTETSTATS_TIME_FRAME << " seconds) ";
|
||||
drawtext(10, statsVerticalOffset + 310, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str());
|
||||
|
||||
|
||||
if (::perfStatsOn) {
|
||||
// Get the PerfStats group details. We need to allocate and array of char* long enough to hold 1+groups
|
||||
|
@ -1297,7 +1269,7 @@ void *networkReceive(void *args)
|
|||
case PACKET_HEADER_ERASE_VOXEL:
|
||||
voxels.parseData(incomingPacket, bytesReceived);
|
||||
break;
|
||||
case PACKET_HEADER_BULK_AVATAR_DATA:
|
||||
case PACKET_HEADER_BULK_AVATAR_DATA:
|
||||
AgentList::getInstance()->processBulkAgentData(&senderAddress,
|
||||
incomingPacket,
|
||||
bytesReceived,
|
||||
|
|
|
@ -1,142 +0,0 @@
|
|||
//
|
||||
// CounterStats.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 2013/04/08.
|
||||
//
|
||||
// Poor-man's counter stats collector class. Useful for collecting running averages
|
||||
// and other stats for countable things.
|
||||
//
|
||||
//
|
||||
|
||||
#include "CounterStats.h"
|
||||
#include <cstdio>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "Systime.h"
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include "shared_Log.h"
|
||||
|
||||
//private:
|
||||
// long int currentCount;
|
||||
// long int currentDelta;
|
||||
// double currentTime;
|
||||
// double totalTime;
|
||||
//
|
||||
// long int countSamples[COUNTETSTATS_SAMPLES_TO_KEEP] = {};
|
||||
// long int deltaSamples[COUNTETSTATS_SAMPLES_TO_KEEP] = {};
|
||||
// double timeSamples[COUNTETSTATS_SAMPLES_TO_KEEP] = {};
|
||||
// int sampleAt;
|
||||
|
||||
|
||||
CounterStatHistory::CounterStatHistory() :
|
||||
currentCount(0),
|
||||
currentDelta(0),
|
||||
currentTime(0.0),
|
||||
lastCount(0),
|
||||
lastTime(0.0),
|
||||
totalTime(0.0),
|
||||
sampleAt(-1),
|
||||
sampleCount(0) {
|
||||
}
|
||||
|
||||
CounterStatHistory::CounterStatHistory(std::string myName) :
|
||||
name(myName),
|
||||
currentCount(0),
|
||||
currentDelta(0),
|
||||
currentTime(0.0),
|
||||
lastCount(0),
|
||||
lastTime(0.0),
|
||||
totalTime(0.0),
|
||||
sampleAt(-1),
|
||||
sampleCount(0) {
|
||||
}
|
||||
|
||||
|
||||
CounterStatHistory::CounterStatHistory(std::string myName, double initialTime, long initialCount) :
|
||||
name(myName),
|
||||
currentCount(initialCount),
|
||||
currentDelta(0),
|
||||
currentTime(initialTime),
|
||||
lastCount(initialCount),
|
||||
lastTime(initialTime),
|
||||
totalTime(initialTime),
|
||||
sampleAt(-1),
|
||||
sampleCount(0) {
|
||||
}
|
||||
|
||||
void CounterStatHistory::init() {
|
||||
currentCount = 0;
|
||||
currentDelta = 0;
|
||||
currentTime = 0.0;
|
||||
lastCount = 0;
|
||||
lastTime = 0.0;
|
||||
totalTime = 0.0;
|
||||
sampleAt = -1;
|
||||
sampleCount = 0;
|
||||
}
|
||||
|
||||
void CounterStatHistory::recordSample(long thisCount) {
|
||||
timeval now;
|
||||
gettimeofday(&now,NULL);
|
||||
double nowSeconds = (now.tv_usec/1000000.0)+(now.tv_sec);
|
||||
this->recordSample(nowSeconds,thisCount);
|
||||
}
|
||||
|
||||
void CounterStatHistory::recordSample(double thisTime, long thisCount) {
|
||||
|
||||
// how much did we change since last sample?
|
||||
long thisDelta = thisCount - this->lastCount;
|
||||
double elapsed = thisTime - this->lastTime;
|
||||
|
||||
// record the latest values
|
||||
this->currentCount = thisCount;
|
||||
this->currentTime = thisTime;
|
||||
this->currentDelta = thisDelta;
|
||||
|
||||
//printLog("CounterStatHistory[%s]::recordSample(thisTime %lf, thisCount= %ld)\n",this->name.c_str(),thisTime,thisCount);
|
||||
|
||||
// if more than 1/10th of a second has passed, then record
|
||||
// things in our rolling history
|
||||
if (elapsed > 0.1) {
|
||||
this->lastTime = thisTime;
|
||||
this->lastCount = thisCount;
|
||||
|
||||
// record it in our history...
|
||||
this->sampleAt = (this->sampleAt+1)%COUNTETSTATS_SAMPLES_TO_KEEP;
|
||||
if (this->sampleCount<COUNTETSTATS_SAMPLES_TO_KEEP) {
|
||||
this->sampleCount++;
|
||||
}
|
||||
this->countSamples[this->sampleAt]=thisCount;
|
||||
this->timeSamples[this->sampleAt]=thisTime;
|
||||
this->deltaSamples[this->sampleAt]=thisDelta;
|
||||
|
||||
//printLog("CounterStatHistory[%s]::recordSample() ACTUALLY RECORDING IT sampleAt=%d thisTime %lf, thisCount= %ld)\n",this->name.c_str(),this->sampleAt,thisTime,thisCount);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
long CounterStatHistory::getRunningAverage() {
|
||||
// before we calculate our running average, always "reset" the current count, with the current time
|
||||
// this will flush out old data, if we haven't been adding any new data.
|
||||
this->recordSample(this->currentCount);
|
||||
|
||||
long runningTotal = 0;
|
||||
double minTime = this->timeSamples[0];
|
||||
double maxTime = this->timeSamples[0];
|
||||
|
||||
for (int i =0; i < this->sampleCount; i++) {
|
||||
minTime = std::min(minTime,this->timeSamples[i]);
|
||||
maxTime = std::max(maxTime,this->timeSamples[i]);
|
||||
runningTotal += this->deltaSamples[i];
|
||||
}
|
||||
|
||||
double elapsedTime = maxTime-minTime;
|
||||
long runningAverage = runningTotal/elapsedTime;
|
||||
return runningAverage;
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
//
|
||||
// CounterStats.h
|
||||
// hifi
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 3/29/13.
|
||||
//
|
||||
// Poor-man's counter stats collector class. Useful for collecting running averages
|
||||
// and other stats for countable things.
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef __hifi__CounterStats__
|
||||
#define __hifi__CounterStats__
|
||||
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
// TIME_FRAME should be SAMPLES_TO_KEEP * TIME_BETWEEN_SAMPLES
|
||||
#define COUNTETSTATS_SAMPLES_TO_KEEP 50
|
||||
#define COUNTETSTATS_TIME_BETWEEN_SAMPLES 0.1
|
||||
#define COUNTETSTATS_TIME_FRAME (COUNTETSTATS_SAMPLES_TO_KEEP*COUNTETSTATS_TIME_BETWEEN_SAMPLES)
|
||||
|
||||
class CounterStatHistory {
|
||||
public:
|
||||
std::string name;
|
||||
|
||||
CounterStatHistory();
|
||||
CounterStatHistory(std::string myName);
|
||||
CounterStatHistory(std::string myName, double initialTime, long initialCount);
|
||||
|
||||
void recordSample(long thisCount);
|
||||
void recordSample(double thisTime, long thisCount);
|
||||
long getRunningAverage();
|
||||
|
||||
long getAverage() {
|
||||
return currentCount/totalTime;
|
||||
};
|
||||
|
||||
double getTotalTime() {
|
||||
return totalTime;
|
||||
};
|
||||
long getCount() {
|
||||
return currentCount;
|
||||
};
|
||||
private:
|
||||
void init();
|
||||
|
||||
long currentCount;
|
||||
long currentDelta;
|
||||
double currentTime;
|
||||
|
||||
long lastCount;
|
||||
double lastTime;
|
||||
|
||||
double totalTime;
|
||||
|
||||
long countSamples[COUNTETSTATS_SAMPLES_TO_KEEP];
|
||||
long deltaSamples[COUNTETSTATS_SAMPLES_TO_KEEP];
|
||||
double timeSamples[COUNTETSTATS_SAMPLES_TO_KEEP];
|
||||
int sampleAt;
|
||||
int sampleCount;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__CounterStat__) */
|
51
libraries/shared/src/SimpleMovingAverage.cpp
Normal file
51
libraries/shared/src/SimpleMovingAverage.cpp
Normal file
|
@ -0,0 +1,51 @@
|
|||
//
|
||||
// SimpleMovingAverage.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 4/18/13.
|
||||
//
|
||||
//
|
||||
|
||||
#include "SharedUtil.h"
|
||||
#include "SimpleMovingAverage.h"
|
||||
|
||||
SimpleMovingAverage::SimpleMovingAverage(float numSamplesToAverage) :
|
||||
_numSamples(0),
|
||||
_numSamplesToAverage(numSamplesToAverage),
|
||||
_average(0),
|
||||
_eventDeltaAverage(0) {
|
||||
}
|
||||
|
||||
int SimpleMovingAverage::updateAverage(float sample) {
|
||||
if (_numSamples > 0) {
|
||||
|
||||
float firstCoefficient = 1 - (1.0f / _numSamplesToAverage);
|
||||
float secondCoefficient = (1.0f / _numSamplesToAverage);
|
||||
|
||||
_average = (firstCoefficient * _average) + (secondCoefficient * sample);
|
||||
|
||||
float eventDelta = (usecTimestampNow() - _lastEventTimestamp) / 1000000;
|
||||
|
||||
if (_numSamples > 1) {
|
||||
_eventDeltaAverage = (firstCoefficient * _eventDeltaAverage) +
|
||||
(secondCoefficient * eventDelta);
|
||||
} else {
|
||||
_eventDeltaAverage = eventDelta;
|
||||
}
|
||||
} else {
|
||||
_average = sample;
|
||||
_eventDeltaAverage = 0;
|
||||
}
|
||||
|
||||
_lastEventTimestamp = usecTimestampNow();
|
||||
|
||||
return ++_numSamples;
|
||||
}
|
||||
|
||||
void SimpleMovingAverage::reset() {
|
||||
_numSamples = 0;
|
||||
}
|
||||
|
||||
float SimpleMovingAverage::getAverageSampleValuePerSecond() {
|
||||
return _average * (1 / _eventDeltaAverage);
|
||||
}
|
34
libraries/shared/src/SimpleMovingAverage.h
Normal file
34
libraries/shared/src/SimpleMovingAverage.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
//
|
||||
// SimpleMovingAverage.h
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 4/18/13.
|
||||
// Based heavily on Brad Hefta-Gaub's CounterStats class (RIP)
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef __hifi__Stats__
|
||||
#define __hifi__Stats__
|
||||
|
||||
#include <iostream>
|
||||
|
||||
class SimpleMovingAverage {
|
||||
public:
|
||||
SimpleMovingAverage(float numSamplesToAverage);
|
||||
|
||||
int updateAverage(float sample);
|
||||
void reset();
|
||||
|
||||
int getSampleCount() { return _numSamples; };
|
||||
float getAverage() { return _average; };
|
||||
float getEventDeltaAverage() { return _eventDeltaAverage; };
|
||||
float getAverageSampleValuePerSecond();
|
||||
private:
|
||||
int _numSamples;
|
||||
int _numSamplesToAverage;
|
||||
double _lastEventTimestamp;
|
||||
float _average;
|
||||
float _eventDeltaAverage;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__Stats__) */
|
|
@ -15,7 +15,6 @@
|
|||
#include "SharedUtil.h"
|
||||
#include "voxels_Log.h"
|
||||
#include "PacketHeaders.h"
|
||||
#include "CounterStats.h"
|
||||
#include "OctalCode.h"
|
||||
#include "VoxelTree.h"
|
||||
#include <fstream> // to load voxels from file
|
||||
|
@ -46,19 +45,17 @@ int boundaryDistanceForRenderLevel(unsigned int renderLevel) {
|
|||
}
|
||||
}
|
||||
|
||||
VoxelTree::VoxelTree() {
|
||||
VoxelTree::VoxelTree() :
|
||||
voxelsCreated(0),
|
||||
voxelsColored(0),
|
||||
voxelsBytesRead(0),
|
||||
voxelsCreatedStats(100),
|
||||
voxelsColoredStats(100),
|
||||
voxelsBytesReadStats(100) {
|
||||
|
||||
rootNode = new VoxelNode();
|
||||
rootNode->octalCode = new unsigned char[1];
|
||||
*rootNode->octalCode = 0;
|
||||
|
||||
// Some stats tracking
|
||||
this->voxelsCreated = 0; // when a voxel is created in the tree (object new'd)
|
||||
this->voxelsColored = 0; // when a voxel is colored/set in the tree (object may have already existed)
|
||||
this->voxelsBytesRead = 0;
|
||||
voxelsCreatedStats.name = "voxelsCreated";
|
||||
voxelsColoredStats.name = "voxelsColored";
|
||||
voxelsBytesReadStats.name = "voxelsBytesRead";
|
||||
|
||||
}
|
||||
|
||||
VoxelTree::~VoxelTree() {
|
||||
|
@ -126,14 +123,14 @@ int VoxelTree::readNodeData(VoxelNode *destinationNode,
|
|||
if (destinationNode->children[i] == NULL) {
|
||||
destinationNode->addChildAtIndex(i);
|
||||
this->voxelsCreated++;
|
||||
this->voxelsCreatedStats.recordSample(this->voxelsCreated);
|
||||
this->voxelsCreatedStats.updateAverage(1);
|
||||
}
|
||||
|
||||
// pull the color for this child
|
||||
memcpy(destinationNode->children[i]->color, nodeData + bytesRead, 3);
|
||||
destinationNode->children[i]->color[3] = 1;
|
||||
this->voxelsColored++;
|
||||
this->voxelsColoredStats.recordSample(this->voxelsColored);
|
||||
this->voxelsColoredStats.updateAverage(1);
|
||||
|
||||
bytesRead += 3;
|
||||
}
|
||||
|
@ -156,7 +153,7 @@ int VoxelTree::readNodeData(VoxelNode *destinationNode,
|
|||
// add a child at that index, if it doesn't exist
|
||||
destinationNode->addChildAtIndex(childIndex);
|
||||
this->voxelsCreated++;
|
||||
this->voxelsCreatedStats.recordSample(this->voxelsCreated);
|
||||
this->voxelsCreatedStats.updateAverage(this->voxelsCreated);
|
||||
}
|
||||
|
||||
// tell the child to read the subsequent data
|
||||
|
@ -184,7 +181,7 @@ void VoxelTree::readBitstreamToTree(unsigned char * bitstream, int bufferSizeByt
|
|||
readNodeData(bitstreamRootNode, bitstream + octalCodeBytes, bufferSizeBytes - octalCodeBytes);
|
||||
|
||||
this->voxelsBytesRead += bufferSizeBytes;
|
||||
this->voxelsBytesReadStats.recordSample(this->voxelsBytesRead);
|
||||
this->voxelsBytesReadStats.updateAverage(bufferSizeBytes);
|
||||
}
|
||||
|
||||
// Note: uses the codeColorBuffer format, but the color's are ignored, because
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#ifndef __hifi__VoxelTree__
|
||||
#define __hifi__VoxelTree__
|
||||
|
||||
#include "CounterStats.h"
|
||||
#include "SimpleMovingAverage.h"
|
||||
|
||||
#include "VoxelNode.h"
|
||||
#include "MarkerNode.h"
|
||||
|
@ -20,13 +20,15 @@ const int TREE_SCALE = 10;
|
|||
|
||||
class VoxelTree {
|
||||
public:
|
||||
// when a voxel is created in the tree (object new'd)
|
||||
long voxelsCreated;
|
||||
// when a voxel is colored/set in the tree (object may have already existed)
|
||||
long voxelsColored;
|
||||
long voxelsBytesRead;
|
||||
|
||||
CounterStatHistory voxelsCreatedStats;
|
||||
CounterStatHistory voxelsColoredStats;
|
||||
CounterStatHistory voxelsBytesReadStats;
|
||||
|
||||
SimpleMovingAverage voxelsCreatedStats;
|
||||
SimpleMovingAverage voxelsColoredStats;
|
||||
SimpleMovingAverage voxelsBytesReadStats;
|
||||
|
||||
VoxelTree();
|
||||
~VoxelTree();
|
||||
|
|
Loading…
Reference in a new issue