diff options
| -rw-r--r-- | indra/integration_tests/llimage_libtest/llimage_libtest.cpp | 89 | ||||
| -rw-r--r-- | indra/llcommon/llmetricperformancetester.cpp | 71 | ||||
| -rw-r--r-- | indra/llcommon/llmetricperformancetester.h | 3 | ||||
| -rw-r--r-- | indra/newview/llfasttimerview.cpp | 74 | ||||
| -rw-r--r-- | indra/newview/llfasttimerview.h | 2 | 
5 files changed, 162 insertions, 77 deletions
| diff --git a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp index 4104527f83..2442313ef2 100644 --- a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp +++ b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp @@ -26,6 +26,7 @@   */  #include "linden_common.h"  #include "llpointer.h" +#include "lltimer.h"  #include "llimage_libtest.h" @@ -49,8 +50,13 @@ static const char USAGE[] = "\n"  " --in <file1 .. file2>            list of image files to load and convert, patterns can be used\n"  " --out <file1 .. file2> OR <type> list of image files to create (assumes same order as --in files)\n"  "                                  OR 3 letters file type extension to convert each input file into\n" +" --logmetrics <metric>            log performance metric and data for <metric>\n" +" --analyzeperformance             create report comparing baseline with current for <metric> provided in --logmetrics\n"  "\n"; +// true when all image loading is done. Used by metric logging thread to know when to stop the thread. +static bool sAllDone = false; +  // Create an empty formatted image instance of the correct type from the filename  LLPointer<LLImageFormatted> create_image(const std::string &filename)  { @@ -202,15 +208,43 @@ void store_output_file(std::list<std::string> &output_filenames, std::list<std::  	}  } +// Holds the metric gathering output in a thread safe way +class LogThread : public LLThread +{ +public: +	std::string mFile; + +	LogThread(std::string& test_name) : LLThread("llimage_libtest log") +	{ +		std::string file_name = test_name + std::string(".slp"); +		mFile = file_name; +	} +		 +	void run() +	{ +		std::ofstream os(mFile.c_str()); +			 +		while (!sAllDone) +		{ +			LLFastTimer::writeLog(os); +			os.flush(); +			ms_sleep(32); +		} +		os.close(); +	}		 +}; +  int main(int argc, char** argv)  {  	// List of input and output files  	std::list<std::string> input_filenames;  	std::list<std::string> output_filenames; +	bool analyze_performance = false;  	// Init whatever is necessary  	ll_init_apr();  	LLImage::initClass(); +	LogThread* fast_timer_log_thread = NULL;	// For performance and metric gathering  	// Analyze command line arguments  	for (int arg = 1; arg < argc; ++arg) @@ -246,7 +280,34 @@ int main(int argc, char** argv)  					break;  				file_name = argv[arg+1];	// Next argument and loop over  			} -		}		 +		} +		else if (!strcmp(argv[arg], "--logmetrics")) +		{ +			// '--logmetrics' needs to be specified with a named test metric argument +			// Note: for the moment, only ImageCompressionTester has been tested +			std::string test_name; +			if ((arg + 1) < argc) +			{ +				test_name = argv[arg+1]; +			} +			if (((arg + 1) >= argc) || (test_name[0] == '-')) +			{ +				// We don't have an argument left in the arg list or the next argument is another option +				std::cout << "No --logmetrics argument given, no perf data will be gathered" << std::endl; +			} +			else +			{ +				LLFastTimer::sMetricLog = TRUE; +				LLFastTimer::sLogName = test_name; +				arg += 1;					// Skip that arg now we know it's a valid test name +				if ((arg + 1) == argc)		// Break out of the loop if we reach the end of the arg list +					break; +			} +		} +		else if (!strcmp(argv[arg], "--analyzeperformance")) +		{ +			analyze_performance = true; +		}  	}  	// Analyze the list of (input,output) files @@ -256,6 +317,14 @@ int main(int argc, char** argv)  		return 0;  	} +	// Create the logging thread if required +	if (LLFastTimer::sMetricLog) +	{ +		LLFastTimer::sLogLock = new LLMutex(NULL); +		fast_timer_log_thread = new LogThread(LLFastTimer::sLogName); +		fast_timer_log_thread->start(); +	} +	  	// Perform action on each input file  	std::list<std::string>::iterator in_file  = input_filenames.begin();  	std::list<std::string>::iterator out_file = output_filenames.begin(); @@ -288,10 +357,26 @@ int main(int argc, char** argv)  		// Output stats on each file  	} -	// Output perf data if required by user +	sAllDone = true; +	 +	// Output perf data if requested by user +	if (analyze_performance) +	{ +		std::cout << "Analyzing performance" << std::endl; +		 +		std::string baseline_name = LLFastTimer::sLogName + "_baseline.slp"; +		std::string current_name  = LLFastTimer::sLogName + ".slp";  +		std::string report_name   = LLFastTimer::sLogName + "_report.csv"; +		 +		LLMetricPerformanceTesterBasic::doAnalysisMetrics(baseline_name, current_name, report_name); +	}  	// Cleanup and exit  	LLImage::cleanupClass(); +	if (fast_timer_log_thread) +	{ +		fast_timer_log_thread->shutdown(); +	}  	return 0;  } diff --git a/indra/llcommon/llmetricperformancetester.cpp b/indra/llcommon/llmetricperformancetester.cpp index 5fa3a5ea07..1f1c633909 100644 --- a/indra/llcommon/llmetricperformancetester.cpp +++ b/indra/llcommon/llmetricperformancetester.cpp @@ -83,7 +83,78 @@ BOOL LLMetricPerformanceTesterBasic::isMetricLogRequested(std::string name)  	return (LLFastTimer::sMetricLog && ((LLFastTimer::sLogName == name) || (LLFastTimer::sLogName == DEFAULT_METRIC_NAME)));  } +/*static*/  +LLSD LLMetricPerformanceTesterBasic::analyzeMetricPerformanceLog(std::istream& is) +{ +	LLSD ret; +	LLSD cur; +	 +	while (!is.eof() && LLSDSerialize::fromXML(cur, is)) +	{ +		for (LLSD::map_iterator iter = cur.beginMap(); iter != cur.endMap(); ++iter) +		{ +			std::string label = iter->first; +			 +			LLMetricPerformanceTesterBasic* tester = LLMetricPerformanceTesterBasic::getTester(iter->second["Name"].asString()) ; +			if(tester) +			{ +				ret[label]["Name"] = iter->second["Name"] ; +				 +				S32 num_of_metrics = tester->getNumberOfMetrics() ; +				for(S32 index = 0 ; index < num_of_metrics ; index++) +				{ +					ret[label][ tester->getMetricName(index) ] = iter->second[ tester->getMetricName(index) ] ; +				} +			} +		} +	} +	 +	return ret; +} + +/*static*/  +void LLMetricPerformanceTesterBasic::doAnalysisMetrics(std::string baseline, std::string target, std::string output) +{ +	if(!LLMetricPerformanceTesterBasic::hasMetricPerformanceTesters()) +	{ +		return ; +	} +	 +	// Open baseline and current target, exit if one is inexistent +	std::ifstream base_is(baseline.c_str()); +	std::ifstream target_is(target.c_str()); +	if (!base_is.is_open() || !target_is.is_open()) +	{ +		llwarns << "'-analyzeperformance' error : baseline or current target file inexistent" << llendl; +		base_is.close(); +		target_is.close(); +		return; +	} +	 +	//analyze baseline +	LLSD base = analyzeMetricPerformanceLog(base_is); +	base_is.close(); +	 +	//analyze current +	LLSD current = analyzeMetricPerformanceLog(target_is); +	target_is.close(); +	//output comparision +	std::ofstream os(output.c_str()); +	 +	os << "Label, Metric, Base(B), Target(T), Diff(T-B), Percentage(100*T/B)\n";  +	for(LLMetricPerformanceTesterBasic::name_tester_map_t::iterator iter = LLMetricPerformanceTesterBasic::sTesterMap.begin() ;  +		iter != LLMetricPerformanceTesterBasic::sTesterMap.end() ; ++iter) +	{ +		LLMetricPerformanceTesterBasic* tester = ((LLMetricPerformanceTesterBasic*)iter->second) ;	 +		tester->analyzePerformance(&os, &base, ¤t) ; +	} +	 +	os.flush(); +	os.close(); +} + +  //----------------------------------------------------------------------------------------------  // LLMetricPerformanceTesterBasic : Tester instance methods  //---------------------------------------------------------------------------------------------- diff --git a/indra/llcommon/llmetricperformancetester.h b/indra/llcommon/llmetricperformancetester.h index 1372f48dcf..b790b636a7 100644 --- a/indra/llcommon/llmetricperformancetester.h +++ b/indra/llcommon/llmetricperformancetester.h @@ -62,6 +62,8 @@ public:  	 */  	virtual void analyzePerformance(std::ofstream* os, LLSD* base, LLSD* current) ; +	static void doAnalysisMetrics(std::string baseline, std::string target, std::string output) ; +  	/**  	 * @return Returns the number of the test metrics in this tester instance.  	 */ @@ -116,6 +118,7 @@ protected:  private:  	void preOutputTestResults(LLSD* sd) ;  	void postOutputTestResults(LLSD* sd) ; +	static LLSD analyzeMetricPerformanceLog(std::istream& is) ;  	std::string mName ;							// Name of this tester instance  	S32 mCount ;								// Current record count diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 92a3b9b2f5..279904b740 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -1149,36 +1149,6 @@ void LLFastTimerView::doAnalysisDefault(std::string baseline, std::string target  	os.close();  } -//------------------------- -//static -LLSD LLFastTimerView::analyzeMetricPerformanceLog(std::istream& is) -{ -	LLSD ret; -	LLSD cur; - -	while (!is.eof() && LLSDSerialize::fromXML(cur, is)) -	{ -		for (LLSD::map_iterator iter = cur.beginMap(); iter != cur.endMap(); ++iter) -		{ -			std::string label = iter->first; - -			LLMetricPerformanceTesterBasic* tester = LLMetricPerformanceTesterBasic::getTester(iter->second["Name"].asString()) ; -			if(tester) -			{ -				ret[label]["Name"] = iter->second["Name"] ; - -				S32 num_of_metrics = tester->getNumberOfMetrics() ; -				for(S32 index = 0 ; index < num_of_metrics ; index++) -				{ -					ret[label][ tester->getMetricName(index) ] = iter->second[ tester->getMetricName(index) ] ; -				} -			} -		} -	} -		 -	return ret; -} -  //static  void LLFastTimerView::outputAllMetrics()  { @@ -1194,48 +1164,6 @@ void LLFastTimerView::outputAllMetrics()  }  //static -void LLFastTimerView::doAnalysisMetrics(std::string baseline, std::string target, std::string output) -{ -	if(!LLMetricPerformanceTesterBasic::hasMetricPerformanceTesters()) -	{ -		return ; -	} - -	// Open baseline and current target, exit if one is inexistent -	std::ifstream base_is(baseline.c_str()); -	std::ifstream target_is(target.c_str()); -	if (!base_is.is_open() || !target_is.is_open()) -	{ -		llwarns << "'-analyzeperformance' error : baseline or current target file inexistent" << llendl; -		base_is.close(); -		target_is.close(); -		return; -	} - -	//analyze baseline -	LLSD base = analyzeMetricPerformanceLog(base_is); -	base_is.close(); - -	//analyze current -	LLSD current = analyzeMetricPerformanceLog(target_is); -	target_is.close(); - -	//output comparision -	std::ofstream os(output.c_str()); -	 -	os << "Label, Metric, Base(B), Target(T), Diff(T-B), Percentage(100*T/B)\n";  -	for(LLMetricPerformanceTesterBasic::name_tester_map_t::iterator iter = LLMetricPerformanceTesterBasic::sTesterMap.begin() ;  -		iter != LLMetricPerformanceTesterBasic::sTesterMap.end() ; ++iter) -	{ -		LLMetricPerformanceTesterBasic* tester = ((LLMetricPerformanceTesterBasic*)iter->second) ;	 -		tester->analyzePerformance(&os, &base, ¤t) ; -	} -	 -	os.flush(); -	os.close(); -} - -//static  void LLFastTimerView::doAnalysis(std::string baseline, std::string target, std::string output)  {  	if(LLFastTimer::sLog) @@ -1246,7 +1174,7 @@ void LLFastTimerView::doAnalysis(std::string baseline, std::string target, std::  	if(LLFastTimer::sMetricLog)  	{ -		doAnalysisMetrics(baseline, target, output) ; +		LLMetricPerformanceTesterBasic::doAnalysisMetrics(baseline, target, output) ;  		return ;  	}  } diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h index 1a54a53f09..b40d7ffc1a 100644 --- a/indra/newview/llfasttimerview.h +++ b/indra/newview/llfasttimerview.h @@ -42,8 +42,6 @@ public:  private:  	static void doAnalysisDefault(std::string baseline, std::string target, std::string output) ; -	static void doAnalysisMetrics(std::string baseline, std::string target, std::string output) ; -	static LLSD analyzeMetricPerformanceLog(std::istream& is) ;  	static LLSD analyzePerformanceLogDefault(std::istream& is) ;  public: | 
