Advertisement
ulfben

Rabin Profiler (2000)

Nov 30th, 2022
935
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.00 KB | None | 0 0
  1. #######
  2. profile.h
  3. #######
  4. /* Copyright (C) Steve Rabin, 2000.
  5.  * All rights reserved worldwide.
  6.  *
  7.  * This software is provided "as is" without express or implied
  8.  * warranties. You may freely copy and compile this source into
  9.  * applications you distribute provided that the copyright text
  10.  * below is included in the resulting source code, for example:
  11.  * "Portions Copyright (C) Steve Rabin, 2000"
  12.  */
  13.  
  14. #ifndef _PROFILE_H
  15. #define _PROFILE_H
  16.  
  17. void ProfileInit( void );
  18. void ProfileBegin(const char* name );
  19. void ProfileEnd( const char* name );
  20. void ProfileDumpOutputToBuffer( void );
  21. void StoreProfileInHistory(const char* name, float percent );
  22. void GetProfileFromHistory(const char* name, float* ave, float* min, float* max );
  23. void ProfileDraw( void );
  24.  
  25. #endif
  26.  
  27.  
  28. #######
  29. profile.cpp
  30. #######
  31.  
  32. /* Copyright (C) Steve Rabin, 2000.
  33.  * All rights reserved worldwide.
  34.  *
  35.  * This software is provided "as is" without express or implied
  36.  * warranties. You may freely copy and compile this source into
  37.  * applications you distribute provided that the copyright text
  38.  * below is included in the resulting source code, for example:
  39.  * "Portions Copyright (C) Steve Rabin, 2000"
  40.  */
  41.  
  42.  
  43. #include "profile.h"
  44. #include "custom_time.h"
  45. //#include "text.h"
  46. #include <string>
  47. #include <iostream>
  48. #include <assert.h>
  49. #include <string.h>
  50. #include <stdio.h>
  51.  
  52.  
  53. typedef struct {
  54.    bool bValid;                 //Whether this data is valid
  55.    unsigned int iProfileInstances;      //# of times ProfileBegin called
  56.    int iOpenProfiles;           //# of times ProfileBegin w/o ProfileEnd
  57.    char szName[256];            //Name of sample
  58.    float fStartTime;            //The current open profile start time
  59.    float fAccumulator;          //All samples this frame added together
  60.    float fChildrenSampleTime;   //Time taken by all children
  61.    unsigned int iNumParents;            //Number of profile parents
  62. } ProfileSample;
  63.  
  64. typedef struct {
  65.    bool bValid;        //Whether the data is valid
  66.    char szName[256];   //Name of the sample
  67.    float fAve;         //Average time per frame (percentage)
  68.    float fMin;         //Minimum time per frame (percentage)
  69.    float fMax;         //Maximum time per frame (percentage)
  70. } ProfileSampleHistory;
  71.  
  72.  
  73.  
  74. #define NUM_PROFILE_SAMPLES 50
  75. ProfileSample g_samples[NUM_PROFILE_SAMPLES];
  76. ProfileSampleHistory g_history[NUM_PROFILE_SAMPLES];
  77. float g_startProfile = 0.0f;
  78. float g_endProfile = 0.0f;
  79. std::string textBox;
  80.  
  81.  
  82. void ProfileInit( void )
  83. {
  84.    unsigned int i;
  85.  
  86.    for( i=0; i<NUM_PROFILE_SAMPLES; i++ ) {
  87.       g_samples[i].bValid = false;
  88.       g_history[i].bValid = false;
  89.    }
  90.  
  91.    g_startProfile = GetExactTime();
  92.  
  93.  
  94.    textBox = "";
  95.  
  96. }
  97.  
  98.  
  99.  
  100.  
  101. void ProfileBegin(const char* name )
  102. {
  103.    unsigned int i = 0;
  104.  
  105.    while( i < NUM_PROFILE_SAMPLES && g_samples[i].bValid == true ) {
  106.       if( strcmp( g_samples[i].szName, name ) == 0 ) {
  107.          //Found the sample
  108.          g_samples[i].iOpenProfiles++;
  109.          g_samples[i].iProfileInstances++;
  110.          g_samples[i].fStartTime = GetExactTime();
  111.          assert( g_samples[i].iOpenProfiles == 1 ); //max 1 open at once
  112.          return;
  113.        }
  114.        i++;
  115.    }
  116.  
  117.    if( i >= NUM_PROFILE_SAMPLES ) {
  118.       assert( !"Exceeded Max Available Profile Samples" );
  119.       return;
  120.    }
  121.  
  122.    strcpy_s( g_samples[i].szName, name );
  123.    g_samples[i].bValid = true;
  124.    g_samples[i].iOpenProfiles = 1;
  125.    g_samples[i].iProfileInstances = 1;
  126.    g_samples[i].fAccumulator = 0.0f;
  127.    g_samples[i].fStartTime = GetExactTime();
  128.    g_samples[i].fChildrenSampleTime = 0.0f;
  129. }
  130.  
  131.  
  132. void ProfileEnd(const char* name )
  133. {
  134.    unsigned int i = 0;
  135.    unsigned int numParents = 0;
  136.  
  137.    while( i < NUM_PROFILE_SAMPLES && g_samples[i].bValid == true )
  138.    {
  139.       if( strcmp( g_samples[i].szName, name ) == 0 )
  140.       {  //Found the sample
  141.          unsigned int inner = 0;
  142.          int parent = -1;
  143.          float fEndTime = GetExactTime();
  144.          g_samples[i].iOpenProfiles--;
  145.  
  146.          //Count all parents and find the immediate parent
  147.          while( g_samples[inner].bValid == true ) {
  148.             if( g_samples[inner].iOpenProfiles > 0 )
  149.             {  //Found a parent (any open profiles are parents)
  150.                numParents++;
  151.                if( parent < 0 )
  152.                {  //Replace invalid parent (index)
  153.                   parent = inner;
  154.                }
  155.                else if( g_samples[inner].fStartTime >=
  156.                         g_samples[parent].fStartTime )
  157.                {  //Replace with more immediate parent
  158.                   parent = inner;
  159.                }
  160.             }
  161.             inner++;
  162.          }
  163.  
  164.          //Remember the current number of parents of the sample
  165.          g_samples[i].iNumParents = numParents;
  166.  
  167.          if( parent >= 0 )
  168.          {  //Record this time in fChildrenSampleTime (add it in)
  169.             g_samples[parent].fChildrenSampleTime += fEndTime -
  170.                                                      g_samples[i].fStartTime;
  171.          }
  172.  
  173.          //Save sample time in accumulator
  174.          g_samples[i].fAccumulator += fEndTime - g_samples[i].fStartTime;
  175.          return;
  176.       }
  177.       i++; 
  178.    }
  179. }
  180.  
  181.  
  182.  
  183. void ProfileDumpOutputToBuffer( void )
  184. {
  185.    unsigned int i = 0;
  186.  
  187.    g_endProfile = GetExactTime();
  188.    textBox.clear();
  189.  
  190.    textBox += ( "  Ave :   Min :   Max :   # : Profile Name\n" );
  191.    textBox += ( "--------------------------------------------\n" );
  192.  
  193.    while( i < NUM_PROFILE_SAMPLES && g_samples[i].bValid == true ) {       
  194.       unsigned int indent = 0;
  195.       float sampleTime, percentTime, aveTime, minTime, maxTime;
  196.       char line[256], name[256], indentedName[256];
  197.       char ave[16], min[16], max[16], num[16];
  198.            
  199.       if( g_samples[i].iOpenProfiles < 0 ) {
  200.          assert( !"ProfileEnd() called without a ProfileBegin()" );
  201.       }
  202.       else if( g_samples[i].iOpenProfiles > 0 ) {
  203.          assert( !"ProfileBegin() called without a ProfileEnd()" );
  204.       }
  205.  
  206.       sampleTime = g_samples[i].fAccumulator - g_samples[i].fChildrenSampleTime;
  207.       percentTime = ( sampleTime / (g_endProfile - g_startProfile ) ) * 100.0f;
  208.  
  209.       aveTime = minTime = maxTime = percentTime;
  210.  
  211.       //Add new measurement into the history and get the ave, min, and max
  212.       StoreProfileInHistory( g_samples[i].szName, percentTime );
  213.       GetProfileFromHistory( g_samples[i].szName, &aveTime, &minTime, &maxTime );
  214.  
  215.       //Format the data
  216.       sprintf_s( ave, "%3.1f", aveTime );
  217.       sprintf_s( min, "%3.1f", minTime );
  218.       sprintf_s( max, "%3.1f", maxTime );
  219.       sprintf_s( num, "%3d", g_samples[i].iProfileInstances );
  220.  
  221.       strcpy_s( indentedName, g_samples[i].szName );
  222.       for( indent=0; indent<g_samples[i].iNumParents; indent++ ) {
  223.          sprintf_s( name, "   %s", indentedName );
  224.          strcpy_s( indentedName, name );
  225.       }
  226.  
  227.       sprintf_s(line,"%5s : %5s : %5s : %3s : %s\n", ave, min, max, num, indentedName);
  228.       textBox +=  line; //Send the line to text buffer
  229.       i++;
  230.    }
  231.  
  232.    {  //Reset samples for next frame
  233.       unsigned int i;
  234.       for( i=0; i<NUM_PROFILE_SAMPLES; i++ ) {
  235.          g_samples[i].bValid = false;
  236.       }
  237.       g_startProfile = GetExactTime();
  238.    }
  239. }
  240.  
  241.  
  242.  
  243.  
  244. void StoreProfileInHistory(const char* name, float percent )
  245. {
  246.    unsigned int i = 0;
  247.    float oldRatio;
  248.    float newRatio = 0.8f * GetElapsedTime();
  249.    if( newRatio > 1.0f ) {
  250.       newRatio = 1.0f;
  251.    }
  252.    oldRatio = 1.0f - newRatio;
  253.  
  254.    while( i < NUM_PROFILE_SAMPLES && g_history[i].bValid == true ) {
  255.       if( strcmp( g_history[i].szName, name ) == 0 )
  256.       {  //Found the sample
  257.          g_history[i].fAve = (g_history[i].fAve*oldRatio) + (percent*newRatio);
  258.          if( percent < g_history[i].fMin ) {
  259.             g_history[i].fMin = percent;
  260.          }
  261.          else {
  262.             g_history[i].fMin = (g_history[i].fMin*oldRatio) + (percent*newRatio);
  263.          }
  264.  
  265.          if( g_history[i].fMin < 0.0f ) {
  266.             g_history[i].fMin = 0.0f;
  267.          }
  268.  
  269.  
  270.          if( percent > g_history[i].fMax ) {
  271.             g_history[i].fMax = percent;
  272.          }
  273.          else {
  274.             g_history[i].fMax = (g_history[i].fMax*oldRatio) + (percent*newRatio);
  275.          }
  276.          return;
  277.       }
  278.       i++;
  279.    }
  280.  
  281.    if( i < NUM_PROFILE_SAMPLES )
  282.    {  //Add to history
  283.       strcpy_s( g_history[i].szName, name );
  284.       g_history[i].bValid = true;
  285.       g_history[i].fAve = g_history[i].fMin = g_history[i].fMax = percent;
  286.    }
  287.    else {
  288.       assert( !"Exceeded Max Available Profile Samples!");
  289.    }
  290. }
  291.  
  292. void GetProfileFromHistory(const char* name, float* ave, float* min, float* max )
  293. {
  294.    unsigned int i = 0;
  295.    while( i < NUM_PROFILE_SAMPLES && g_history[i].bValid == true ) {
  296.       if( strcmp( g_history[i].szName, name ) == 0 )
  297.       {  //Found the sample
  298.          *ave = g_history[i].fAve;
  299.          *min = g_history[i].fMin;
  300.          *max = g_history[i].fMax;
  301.          return;
  302.       }
  303.       i++;
  304.    }   
  305.    *ave = *min = *max = 0.0f;
  306. }
  307.  
  308.  
  309. void ProfileDraw( void )
  310. {
  311.  
  312.    std::cout << textBox << "\n";
  313. }
  314.  
  315.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement