📄 rvprftrace.c
字号:
/******************************************************************************
Filename : rvprftrace.c
Description : Performance Trace objects
Note: high precision time functions implemented only for Windows
No thread safe
******************************************************************************
Copyright (c) 1999 RADVision Inc.
************************************************************************
NOTICE:
This document contains information that is proprietary to RADVision LTD.
No part of this publication may be reproduced in any form whatsoever
without written prior approval by RADVision LTD..
RADVision LTD. reserves the right to revise this publication and make
changes without obligation to notify any person of such revisions or
changes.
******************************************************************************
$Revision:1.0$
$Date:9/15/00$
$Author:Dan Elbert$
******************************************************************************/
#ifdef RV_PRFTRACE_ON
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include "rvmem.h"
#include "rvprftrace.h"
/* Private functions */
void rvPrfTraceNormalize(RvPrfTrace * p);
__int64 rvPrfTraceGetFrame(void);
__int64 rvPrfTraceGetStamp(void);
char* rvPrfTraceGetCheckpointName(int nameF, char *lpName,void * userdata);
static void rvPrfTraceOutput(RvPrfTrace * p) {
int i,j;
FILE * fp;
char filename[255];
for(i=0;i<p->chkpnum;i++) {
/* Open file */
strcpy(filename,rvPrfTraceGetCheckpointName(i,0,p));
strcat(filename,".txt");
if( (fp=fopen(filename,"a")) == NULL )
continue;
fprintf(fp,"%-15s%-15s\n",rvPrfTraceGetCheckpointName(i,0,p),rvPrfTraceGetCheckpointName(i,0,p));
fprintf(fp,"%-12s%-3s%-15s\n","Total_time"," ","Net_time");
for(j=0;j<p->max;j++) {
if(i==p->trace_array[j].chkp_id) {
fprintf(fp,"%-15u",p->trace_array[j].elapsed);
fprintf(fp,"%-15u\n",p->trace_array[j].net);
}
}
fclose(fp);
}
}
static void rvPrfTraceOutputAvg(RvPrfTrace * p) {
int i;
double total = 0;
FILE * fp;
if( (fp=fopen("prf_avg.txt","a")) == NULL )
return;
for(i=0;i<p->chkpnum;i++) {
fprintf(fp,"%-30s: %-20f mcsec, %-10u calls\n",
rvPrfTraceGetCheckpointName(i,0,p),
p->checkpoint_avg[i].avg_time,p->checkpoint_avg[i].count);
total+=p->checkpoint_avg[i].avg_time;
}
fprintf(fp,"Total average time: %-20f mcsecs\n",total);
fprintf(fp,"\n");
fclose(fp);
}
void rvPrfTraceStart(RvPrfTrace * p, int checkpoint_id) {
if(p->trace==rvTrue) {
/*printf("Start function %s,line %d\n",rvPrfTraceGetCheckpointName(checkpoint_id,0,p),p->next_element);*/
p->trace_array[p->next_element].chkp_id = checkpoint_id;
p->trace_array[p->next_element].start = rvPrfTraceGetStamp();
p->trace_array[p->next_element].end = 0;
/*printf("Start time: %lu\n",p->trace_array[p->next_element].start);*/
/* Push the element index in the stack */
p->call_stack[p->stack_idx++] = p->next_element;
/* Increment the next element */
p->next_element++;
}
}
static void rvPrfTraceProcess(RvPrfTrace * p) {
rvPrfTraceNormalize(p);
p->max = p->next_element;
p->next_element = 0;
p->stack_idx = 0;
(p->process)(p);
}
void rvPrfTraceStop(RvPrfTrace * p) {
if(p->trace==rvTrue) {
/* Pop the element index from the stack */
int elem = p->call_stack[--p->stack_idx];
p->trace_array[elem].end = rvPrfTraceGetStamp();
/*printf("Stop function %s,line %d\n",rvPrfTraceGetCheckpointName(p->trace_array[elem].chkp_id,0,p),elem);*/
/*printf("End time: %lu\n",p->trace_array[elem].end);*/
/* Full array */
if( (p->next_element+RV_PRFTRACE_MAX_CALLS*10)>=RV_PRFTRACE_MAX_ELEM) {
if(p->stack_idx==0)
rvPrfTraceProcess(p);
}
}
}
/* Default callback to retrieve function name */
static char* rvPrfTraceGetCheckpointName(int nameF, char* lpName,void * userdata) {
RvPrfTrace * p = (RvPrfTrace*)userdata;
return p->checkpoint_arr[nameF];
}
/* Arguments
checkpoint_arr - pointer to array with function names (mapped to function index)
num_of_checkpoints - number of functions being traced
process - function to be called when the array is full, to process and output results
process_final - final processing, called when trace is destructed
*/
void rvPrfTraceConstruct(RvPrfTrace * p,char** checkpoint_arr,int num_of_checkpoints) {
p->next_element = 0;
p->stack_idx = 0;
p->checkpoint_arr = checkpoint_arr;
p->chkpnum = num_of_checkpoints;
p->checkpoint_avg = rvMemAlloc(sizeof(RvPrfTraceChkpAvg)*num_of_checkpoints);
memset((void*)p->checkpoint_avg,0,sizeof(RvPrfTraceChkpAvg)*num_of_checkpoints);
p->get_chkname = rvPrfTraceGetCheckpointName;
p->process = rvPrfTraceOutput;
p->process_final = rvPrfTraceOutputAvg;
p->trace = rvTrue;
}
void rvPrfTraceDestruct(RvPrfTrace * p) {
rvPrfTraceProcess(p);
(p->process_final)(p);
rvMemFree(p->checkpoint_avg);
}
void rvPrfTraceEnable(RvPrfTrace * p) {
p->trace = rvTrue;
}
void rvPrfTraceDisable(RvPrfTrace * p) {
p->trace = rvFalse;
}
static __int64 rvPrfTraceGetFrame(void) {
LARGE_INTEGER lpFrequency;
QueryPerformanceFrequency( &lpFrequency );
return lpFrequency.QuadPart;
}
static __int64 rvPrfTraceGetStamp(void) {
LARGE_INTEGER lpPerformanceCount;
QueryPerformanceCounter( &lpPerformanceCount );
return lpPerformanceCount.QuadPart ;
}
/* Adjust the net time spent in entry i, by substracting the time spent in
functions called from the main function. Recursive */
static int AdjustNetTime(RvPrfTrace * p,int i) {
int next,j=i+1;
while(p->trace_array[i].end > p->trace_array[j].start
&& j < p->next_element ) {
next = AdjustNetTime(p,j);
p->trace_array[i].net-=p->trace_array[j].elapsed;
j = next;
}
return j;
}
static void rvPrfTraceNormalize(RvPrfTrace * p) {
int i,f;
__int64 result;
__int64 freqF;
double freq;
double * acc = rvMemAlloc(sizeof(double)*p->chkpnum); /* Accumulated time */
int * fcnt = rvMemAlloc(sizeof(int)*p->chkpnum);
freqF = rvPrfTraceGetFrame();
freq = (long double)freqF / 1000000;
memset((void*)acc,0,sizeof(double)*p->chkpnum);
memset((void*)fcnt,0,sizeof(int)*p->chkpnum);
/* Calculate elapsed time */
for(i = 0; i < p->next_element; i++)
{
result = p->trace_array[i].end - p->trace_array[i].start;
if(p->trace_array[i].end && p->trace_array[i].start) {
p->trace_array[i].elapsed = result / (__int64)freq;
p->trace_array[i].net = p->trace_array[i].elapsed;
}
else
p->trace_array[i].elapsed = p->trace_array[i].net = 0;
}
/* Substract from the time the time actually spent in another function */
for(i = 0; i < p->next_element; ) {
i = AdjustNetTime(p,i);
}
/* Calculate running average */
for(i = 0; i < p->next_element; i++) {
f = (int)p->trace_array[i].chkp_id;
acc[f]+=p->trace_array[i].net;
fcnt[f]++;
}
for(i=0;i<p->chkpnum;i++) {
if(fcnt[i]) {
p->checkpoint_avg[i].avg_time = ( p->checkpoint_avg[i].avg_time*p->checkpoint_avg[i].count +
acc[i] ) / (p->checkpoint_avg[i].count+fcnt[i]);
p->checkpoint_avg[i].count+=fcnt[i];
}
}
rvMemFree(acc);
rvMemFree(fcnt);
}
#endif /* RV_PRFTRACE_ON */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -