Fixed a couple of complier warnings, and added a new PerfStat class for monitoring runtime performance

This commit is contained in:
ZappoMan 2013-03-31 20:43:23 -07:00
parent 91cac33cec
commit ad0b2f024b
5 changed files with 196 additions and 4 deletions

View file

@ -147,7 +147,7 @@ int main(int argc, char* argv[])
srand(time(0));
int AUDIO_UDP_SEND_PORT = 1500 + (rand() % (int)(1500 - 2000 + 1));
UDPSocket *streamSocket = new UDPSocket(AUDIO_UDP_SEND_PORT);
streamSocket = new UDPSocket(AUDIO_UDP_SEND_PORT);
if (processParameters(argc, argv)) {
if (sourceAudioFile) {

View file

@ -53,6 +53,7 @@
#include "Oscilloscope.h"
#include "UDPSocket.h"
#include "SerialInterface.h"
#include <PerfStat.h>
#include <SharedUtil.h>
using namespace std;
@ -257,7 +258,18 @@ void display_stats(void)
voxelStats << "Voxels Rendered: " << voxels.getVoxelsRendered();
drawtext(10,70,0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str());
// Get the PerfStats group details. We need to allocate and array of char* long enough to hold 1+groups
char** perfStatLinesArray = new char*[PerfStat::getGroupCount()+1];
int lines = PerfStat::DumpStats(perfStatLinesArray);
int atZ = 150; // arbitrary place on screen that looks good
for (int line=0; line < lines; line++) {
drawtext(10,atZ,0.10f, 0, 1.0, 0, perfStatLinesArray[line]);
delete perfStatLinesArray[line]; // we're responsible for cleanup
perfStatLinesArray[line]=NULL;
atZ+=20; // height of a line
}
delete []perfStatLinesArray; // we're responsible for cleanup
/*
std::stringstream angles;
angles << "render_yaw: " << myHead.getRenderYaw() << ", Yaw: " << myHead.getYaw();
@ -272,7 +284,6 @@ void display_stats(void)
myHead.getYaw(), myHead.getRenderYaw());
drawtext(10, 50, 0.10, 0, 1.0, 0, adc);
*/
}
void initDisplay(void)
@ -464,6 +475,8 @@ int render_test_direction = 1;
void display(void)
{
PerfStat("display");
glEnable (GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LINE_SMOOTH);
@ -777,6 +790,7 @@ void *networkReceive(void *args)
while (!stopNetworkReceiveThread) {
if (agentList.getAgentSocket().receive(&senderAddress, incomingPacket, &bytesReceived)) {
PerfStat("networkReceive receive()");
packetcount++;
bytescount += bytesReceived;

View file

@ -30,7 +30,7 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif _WIN32
#endif //_WIN32
const unsigned short MIXER_LISTEN_PORT = 55443;

102
shared/src/PerfStat.cpp Normal file
View file

@ -0,0 +1,102 @@
//
// HiFiPerfStat.cpp
// hifi
//
// Created by Brad Hefta-Gaub on 3/29/13.
//
// Poor-man's performance stats collector class. Useful for collecting timing
// details from various portions of the code.
//
//
#include "PerfStat.h"
#include <cstdio>
#include <sys/time.h>
#include <string>
#include <map>
// Static class members initialization here!
std::map<std::string,PerfStatHistory,std::less<std::string> > PerfStat::groupHistoryMap;
bool PerfStat::wantDebugOut = false;
timeval PerfStat::firstDumpTime;
bool PerfStat::firstDumpTimeSet = false;
// Constructor handles starting the timer
PerfStat::PerfStat(std::string groupName) {
this->group = groupName;
gettimeofday(&this->start,NULL);
// If this is our first ever PerfStat object, we'll also initialize this
if (!firstDumpTimeSet) {
gettimeofday(&firstDumpTime,NULL);
firstDumpTimeSet=true;
}
}
// Destructor handles recording all of our stats
PerfStat::~PerfStat() {
timeval end;
gettimeofday(&end,NULL);
double elapsed = ((end.tv_usec-start.tv_usec)/1000000.0)+(end.tv_sec-start.tv_sec);
double average = elapsed;
double totalTime = elapsed;
long int count = 1;
// check to see if this group exists in the history...
if (groupHistoryMap.find(group) == groupHistoryMap.end()) {
groupHistoryMap[group]=PerfStatHistory(group,elapsed,1);
} else {
PerfStatHistory history = groupHistoryMap[group];
history.recordTime(elapsed);
groupHistoryMap[group] = history;
average = history.getAverage();
count = history.getCount();
totalTime = history.getTotalTime();
}
if (wantDebugOut) {
printf("PerfStats: %s elapsed:%f average:%lf count:%ld total:%lf ut:%d us:%d ue:%d t:%ld s:%ld e:%ld\n",
this->group.c_str(),elapsed,average,count,totalTime,
(end.tv_usec-start.tv_usec),start.tv_usec,end.tv_usec,
(end.tv_sec-start.tv_sec),start.tv_sec,end.tv_sec
);
}
};
// How many groups have we added?
int PerfStat::getGroupCount() {
return groupHistoryMap.size();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Method: DumpStats()
// Description: Generates some lines of debug stats for all the groups of PerfStats you've created.
// Note: Caller is responsible for allocating an array of char*'s that is large enough to hold
// groupCount + 1. Caller is also responsible for deleting all this memory.
int PerfStat::DumpStats(char** array) {
// If we haven't yet set a dump time, we'll also initialize this now, but this is unlikely
if (!firstDumpTimeSet) {
gettimeofday(&firstDumpTime,NULL);
firstDumpTimeSet=true;
}
timeval now;
gettimeofday(&now,NULL);
double elapsed = ((now.tv_usec-firstDumpTime.tv_usec)/1000000.0)+(now.tv_sec-firstDumpTime.tv_sec);
array[0] = new char[MAX_PERFSTAT_DEBUG_LINE_LEN];
snprintf(array[0],MAX_PERFSTAT_DEBUG_LINE_LEN,"PerfStats:");
int lineCount=1;
// For each active performance group
for (PerfStatMapItr i = groupHistoryMap.begin(); i != groupHistoryMap.end(); i++) {
float percent = (i->second.getTotalTime()/elapsed) * 100.0;
array[lineCount] = new char[MAX_PERFSTAT_DEBUG_LINE_LEN];
snprintf(array[lineCount],MAX_PERFSTAT_DEBUG_LINE_LEN,"%s Avg: %lf Num: %ld TTime: %lf (%.2f%%)",
i->second.group.c_str(),i->second.getAverage(),i->second.getCount(),i->second.getTotalTime(),percent);
lineCount++;
}
return lineCount;
}

76
shared/src/PerfStat.h Normal file
View file

@ -0,0 +1,76 @@
//
// HiFiPerfStat.h
// hifi
//
// Created by Brad Hefta-Gaub on 3/29/13.
//
// Poor-man's performance stats collector class. Useful for collecting timing
// details from various portions of the code.
//
//
#ifndef __hifi__PerfStat__
#define __hifi__PerfStat__
#include <cstring>
#include <string>
#include <map>
class PerfStatHistory {
private:
long int count;
double totalTime;
public:
std::string group;
PerfStatHistory(): count(0), totalTime(0.0) {};
PerfStatHistory(std::string myGroup, double initialTime, long int initialCount) :
count(initialCount), totalTime(initialTime), group(myGroup) {};
void recordTime(double thisTime) {
totalTime+=thisTime;
count++;
};
double getAverage() {
return totalTime/count;
};
double getTotalTime() {
return totalTime;
};
long int getCount() {
return count;
};
// needed for map template? Maybe not.
bool operator<( const PerfStatHistory& other) const {
return group < other.group;
}
};
#define MAX_PERFSTAT_DEBUG_LINE_LEN 200
class PerfStat {
private:
static std::map<std::string,PerfStatHistory,std::less<std::string> > groupHistoryMap;
static timeval firstDumpTime;
static bool firstDumpTimeSet;
std::string group;
timeval start;
public:
PerfStat(std::string groupName);
~PerfStat();
// Format debug stats into buffer, returns number of "lines" of stats
static int DumpStats(char** array);
static int getGroupCount();
static bool wantDebugOut;
};
typedef std::map<std::string,PerfStatHistory,std::less<std::string> >::iterator PerfStatMapItr;
#endif /* defined(__hifi__PerfStat__) */