SH-1292 Remove outliers from graphs in scene console to make a more useful view.

master
Dave Parks 2011-04-07 00:29:02 -05:00
parent e52613aad6
commit f90eb750f1
3 changed files with 75 additions and 74 deletions

View File

@ -29,6 +29,7 @@
#include <cmath>
#include <cstdlib>
#include <vector>
#include "lldefs.h"
//#include "llstl.h" // *TODO: Remove when LLString is gone
//#include "llstring.h" // *TODO: Remove when LLString is gone
@ -497,6 +498,44 @@ inline F32 llgaussian(F32 x, F32 o)
return 1.f/(F_SQRT_TWO_PI*o)*powf(F_E, -(x*x)/(2*o*o));
}
//helper function for removing outliers
template <class VEC_TYPE>
inline void ll_remove_outliers(std::vector<VEC_TYPE>& data, F32 k)
{
if (data.size() < 100)
{ //not enough samples
return;
}
VEC_TYPE Q1 = data[data.size()/4];
VEC_TYPE Q3 = data[data.size()-data.size()/4-1];
VEC_TYPE min = Q1-k*(Q3-Q1);
VEC_TYPE max = Q3+k*(Q3-Q1);
U32 i = 0;
while (i < data.size() && data[i] < min)
{
i++;
}
S32 j = data.size()-1;
while (j > 0 && data[j] > max)
{
j--;
}
if (j < data.size()-1)
{
data.erase(data.begin()+j, data.end());
}
if (i > 0)
{
data.erase(data.begin(), data.begin()+i);
}
}
// Include simd math header
#include "llsimdmath.h"

View File

@ -1040,43 +1040,6 @@ void saveChart(const std::string& label, const char* suffix, LLImageRaw* scratch
result->save(out_file);
}
template <class VEC_TYPE>
void removeOutliers(std::vector<VEC_TYPE>& data, F32 k)
{
if (data.size() < 100)
{ //not enough samples
return;
}
VEC_TYPE Q1 = data[data.size()/4];
VEC_TYPE Q3 = data[data.size()-data.size()/4-1];
VEC_TYPE min = Q1-k*(Q3-Q1);
VEC_TYPE max = Q3+k*(Q3-Q1);
U32 i = 0;
while (i < data.size() && data[i] < min)
{
i++;
}
S32 j = data.size()-1;
while (j > 0 && data[j] > max)
{
j--;
}
if (j < data.size()-1)
{
data.erase(data.begin()+j, data.end());
}
if (i > 0)
{
data.erase(data.begin(), data.begin()+i);
}
}
//static
void LLFastTimerView::exportCharts(const std::string& base, const std::string& target)
{
@ -1206,22 +1169,22 @@ void LLFastTimerView::exportCharts(const std::string& base, const std::string& t
const U32 OUTLIER_CUTOFF = 512;
if (base_times.size() > OUTLIER_CUTOFF)
{
removeOutliers(base_times, 1.f);
ll_remove_outliers(base_times, 1.f);
}
if (base_execution.size() > OUTLIER_CUTOFF)
{
removeOutliers(base_execution, 1.f);
ll_remove_outliers(base_execution, 1.f);
}
if (cur_times.size() > OUTLIER_CUTOFF)
{
removeOutliers(cur_times, 1.f);
ll_remove_outliers(cur_times, 1.f);
}
if (cur_execution.size() > OUTLIER_CUTOFF)
{
removeOutliers(cur_execution, 1.f);
ll_remove_outliers(cur_execution, 1.f);
}

View File

@ -36,6 +36,11 @@
LLSceneView* gSceneView = NULL;
//borrow this helper function from llfasttimerview.cpp
template <class VEC_TYPE>
void removeOutliers(std::vector<VEC_TYPE>& data, F32 k);
LLSceneView::LLSceneView(const LLRect& rect)
: LLFloater(LLSD())
{
@ -72,8 +77,11 @@ void LLSceneView::draw()
//object sizes
std::vector<F32> size[2];
std::vector<U32> triangles[2];
std::vector<U32> visible_triangles[2];
std::vector<S32> triangles[2];
std::vector<S32> visible_triangles[2];
S32 total_visible_triangles[] = {0, 0};
S32 total_triangles[] = {0, 0};
U32 object_count = 0;
@ -97,9 +105,14 @@ void LLSceneView::draw()
F32 radius = object->getScale().magVec();
size[idx].push_back(radius);
visible_triangles[idx].push_back(volume->getNumTriangles());
triangles[idx].push_back(object->getHighLODTriangleCount());
S32 visible = volume->getNumTriangles();
S32 high_triangles = object->getHighLODTriangleCount();
total_visible_triangles[idx] += visible;
total_triangles[idx] += high_triangles;
visible_triangles[idx].push_back(visible);
triangles[idx].push_back(high_triangles);
}
}
}
@ -116,6 +129,8 @@ void LLSceneView::draw()
{ //display graph of object sizes
std::sort(size[idx].begin(), size[idx].end());
ll_remove_outliers(size[idx], 1.f);
LLRect size_rect;
if (idx == 0)
@ -180,8 +195,9 @@ void LLSceneView::draw()
if (!triangles[idx].empty())
{ //plot graph of visible/total triangles
std::sort(triangles[idx].begin(), triangles[idx].end());
std::sort(visible_triangles[idx].begin(), visible_triangles[idx].end());
ll_remove_outliers(triangles[idx], 1.f);
LLRect tri_rect;
if (idx == 0)
{
@ -194,19 +210,17 @@ void LLSceneView::draw()
gl_rect_2d(tri_rect, LLColor4::white, false);
U32 tri_domain[] = { 65536, 0 };
llassert(triangles[idx].size() == visible_triangles[idx].size());
//get domain of sizes
S32 tri_domain[] = { 65536, 0 };
//get domain of triangle counts
for (U32 i = 0; i < triangles[idx].size(); ++i)
{
tri_domain[0] = llmin(visible_triangles[idx][i], llmin(tri_domain[0], triangles[idx][i]));
tri_domain[1] = llmax(visible_triangles[idx][i], llmax(tri_domain[1], triangles[idx][i]));
tri_domain[0] = llmin(tri_domain[0], triangles[idx][i]);
tri_domain[1] = llmax(tri_domain[1], triangles[idx][i]);
}
U32 triangle_range = tri_domain[1]-tri_domain[0];
U32 count = triangles[idx].size();
U32 total = 0;
@ -234,31 +248,16 @@ void LLSceneView::draw()
gGL.flush();
U32 total_visible = 0;
gGL.begin(LLRender::LINE_STRIP);
//plot visible triangles
count = visible_triangles[idx].size();
for (U32 i = 0; i < count; ++i)
{
U32 tri_count = visible_triangles[idx][i];
total_visible += tri_count;
F32 y = (F32) (tri_count-tri_domain[0])/triangle_range*tri_rect.getHeight()+tri_rect.mBottom;
F32 x = (F32) i / count * tri_rect.getWidth() + tri_rect.mLeft;
gGL.vertex2f(x,y);
if (i%4096 == 0)
{
gGL.end();
gGL.flush();
gGL.begin(LLRender::LINE_STRIP);
}
}
gGL.end();
gGL.flush();
std::string label = llformat("%s Object Triangle Counts (Ktris) -- Min: %.2f Max: %.2f Mean: %.2f Median: %.2f (%.2f/%.2f visible) -- %d samples",
category[idx], tri_domain[0]/1024.f, tri_domain[1]/1024.f, (total/count)/1024.f, triangles[idx][count/2]/1024.f, total_visible/1024.f, total/1024.f, count);
category[idx], tri_domain[0]/1024.f, tri_domain[1]/1024.f, (total/count)/1024.f, triangles[idx][count/2]/1024.f, total_visible_triangles[idx]/1024.f, total_triangles[idx]/1024.f, count);
LLFontGL::getFontMonospace()->renderUTF8(label,
0 , tri_rect.mLeft, tri_rect.mTop+margin, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP);