Rough support for profiling replay mode and scripts

This was SVN commit r10634.
This commit is contained in:
Ykkrosh 2011-11-29 20:32:43 +00:00
parent 4da8bf001f
commit 8492426a14
5 changed files with 118 additions and 26 deletions

View File

@ -524,3 +524,28 @@ const char* CProfiler2::ConstructJSONResponse(std::ostream& stream, const std::s
return NULL;
}
void CProfiler2::SaveToFile()
{
OsPath path = psLogDir()/"profile2.jsonp";
std::ofstream stream(OsString(path).c_str(), std::ofstream::out | std::ofstream::trunc);
std::vector<ThreadStorage*> threads;
{
CScopeLock lock(m_Mutex);
threads = m_Threads;
}
stream << "profileDataCB({\"threads\": [\n";
for (size_t i = 0; i < threads.size(); ++i)
{
if (i != 0)
stream << ",\n";
stream << "{\"name\":\"" << CStr(threads[i]->GetName()).EscapeToPrintableASCII() << "\",\n";
stream << "\"data\": ";
ConstructJSONResponse(stream, threads[i]->GetName());
stream << "\n}";
}
stream << "\n]});\n";
}

View File

@ -347,6 +347,12 @@ public:
*/
const char* ConstructJSONResponse(std::ostream& stream, const std::string& thread);
/**
* Call in any thread to save a JSONP representation of the buffers
* for all threads, to a file named profile2.jsonp in the logs directory.
*/
void SaveToFile();
double GetTime()
{
return timer_Time();

View File

@ -203,8 +203,15 @@ void CReplayPlayer::Replay()
}
else if (type == "end")
{
game.GetSimulation2()->Update(turnLength, commands);
commands.clear();
{
g_Profiler2.RecordFrameStart();
PROFILE2("frame");
g_Profiler2.IncrementFrameNumber();
PROFILE2_ATTR("%d", g_Profiler2.GetFrameNumber());
game.GetSimulation2()->Update(turnLength, commands);
commands.clear();
}
// std::string hash;
// bool ok = game.GetSimulation2()->ComputeStateHash(hash, true);
@ -227,6 +234,8 @@ void CReplayPlayer::Replay()
}
}
g_Profiler2.SaveToFile();
std::string hash;
bool ok = game.GetSimulation2()->ComputeStateHash(hash, false);
ENSURE(ok);

View File

@ -384,28 +384,28 @@ JSBool deepcopy(JSContext* cx, uintN argc, jsval* vp)
JSBool ProfileStart(JSContext* cx, uintN argc, jsval* vp)
{
if (CProfileManager::IsInitialised() && ThreadUtil::IsMainThread())
const char* name = "(ProfileStart)";
if (argc >= 1)
{
const char* name = "(ProfileStart)";
std::string str;
if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], str))
return JS_FALSE;
if (argc >= 1)
{
std::string str;
if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], str))
return JS_FALSE;
typedef boost::flyweight<
std::string,
boost::flyweights::no_tracking,
boost::flyweights::no_locking
> StringFlyweight;
typedef boost::flyweight<
std::string,
boost::flyweights::no_tracking,
boost::flyweights::no_locking
> StringFlyweight;
name = StringFlyweight(str).get().c_str();
}
g_Profiler.StartScript(name);
name = StringFlyweight(str).get().c_str();
}
if (CProfileManager::IsInitialised() && ThreadUtil::IsMainThread())
g_Profiler.StartScript(name);
g_Profiler2.RecordRegionEnter(name);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE;
}
@ -413,9 +413,9 @@ JSBool ProfileStart(JSContext* cx, uintN argc, jsval* vp)
JSBool ProfileStop(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* vp)
{
if (CProfileManager::IsInitialised() && ThreadUtil::IsMainThread())
{
g_Profiler.Stop();
}
g_Profiler2.RecordRegionLeave("(ProfileStop)");
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE;

View File

@ -52,6 +52,40 @@ var g_used_colours = {};
var g_data;
function refresh()
{
if (1)
refresh_live();
else
refresh_jsonp('../../../binaries/system/profile2.jsonp');
}
function refresh_jsonp(url)
{
var script = document.createElement('script');
window.profileDataCB = function(data)
{
script.parentNode.removeChild(script);
var threads = [];
data.threads.forEach(function(thread) {
var canvas = $('<canvas width="1600" height="160"></canvas>');
thread.data.events.pop();
threads.push({'name': thread.name, 'data': thread.data, 'canvas': canvas.get(0)});
});
g_data = { 'threads': threads };
var range = {'seconds': 0.05};
rebuild_canvases();
update_display(range);
};
script.src = url;
document.body.appendChild(script);
}
function refresh_live()
{
$.ajax({
url: 'http://127.0.0.1:8000/overview',
@ -59,7 +93,7 @@ function refresh()
success: function (data) {
var threads = [];
data.threads.forEach(function(thread) {
var canvas = $('<canvas width="1600" height="128"></canvas>');
var canvas = $('<canvas width="1600" height="160"></canvas>');
threads.push({'name': thread.name, 'canvas': canvas.get(0)});
});
var callback_data = { 'threads': threads, 'completed': 0 };
@ -93,7 +127,7 @@ function refresh_thread(thread, callback_data)
rebuild_canvases();
update_display(range);
}
}
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Failed to connect to server ("'+textStatus+'")');
@ -349,7 +383,7 @@ function compute_intervals(data, range)
continue;
var interval = stack.pop();
if (data[i][2] != interval.id)
if (data[i][2] != interval.id && data[i][2] != '(ProfileStop)')
alert('inconsistent interval ids ('+interval.id+' / '+data[i][2]+')');
if (!g_used_colours[interval.id])
@ -411,6 +445,23 @@ function display_frames(data, canvas)
}
};
// var y_per_second = 1000;
var y_per_second = 100;
[16, 33, 200, 500].forEach(function(t) {
var y1 = canvas.height;
var y0 = y1 - t/1000*y_per_second;
var y = Math.floor(y0) + 0.5;
ctx.beginPath();
ctx.moveTo(xpadding, y);
ctx.lineTo(canvas.width - xpadding, y);
ctx.strokeStyle = 'rgb(255, 0, 0)';
ctx.stroke();
ctx.fillStyle = 'rgb(255, 0, 0)';
ctx.fillText(t+'ms', 0, y-2);
});
ctx.strokeStyle = 'rgb(0, 0, 0)';
ctx.fillStyle = 'rgb(255, 255, 255)';
for (var i = 0; i < data.frames.length; ++i)
@ -421,7 +472,7 @@ function display_frames(data, canvas)
var x0 = xpadding + dx*(frame.t0 - tmin);
var x1 = x0 + dx*duration;
var y1 = canvas.height;
var y0 = y1 - duration*1000;
var y0 = y1 - duration*y_per_second;
ctx.beginPath();
ctx.rect(x0, y0, x1-x0, y1-y0);
@ -662,7 +713,8 @@ function set_frames_zoom_handlers(canvas0)
var relativeX = event.pageX - this.offsetLeft;
var relativeY = event.pageY - this.offsetTop;
var width = 0.001 + 0.5 * relativeY / canvas0.height;
// var width = 0.001 + 0.5 * relativeY / canvas0.height;
var width = 0.001 + 5 * relativeY / canvas0.height;
var tavg = zdata.x_to_t(relativeX);
var tmax = tavg + width/2;