|
/************************************************************/
//
// file: benchmark.h
//
// purpose: code block execution speed 'benchmark':
// executes two code blocks, measures the
// execution time in cycles and prints
// a simple summary to stdout and log.
//
// copyright: (c) 2005 - 2006 Oto Sp�l
//
// This software is provided 'as-is', without any
// express or implied warranty. In no event will the
// authors be held liable for any damages arising from
// the use of this software.
//
// Permission is granted to anyone to use this software
// for any purpose, including commercial applications,
// and to alter it and redistribute it freely, subject
// to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is
// not required.
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original
// software.
// 3. This notice may not be removed or altered from any
// source distribution.
//
// history: 2005-11-03 OS
// - file crated
// 2005-11-05 OS
// - added support for loop tests
// - measuring algorithm updated
// - added code caching
// 2005-11-08 OS
// - support for multiple test
// - output to log file
// - cmdline args
// - IP flag manipulation
//
// contact: info@armego.sk
// www.armego.sk
//
/************************************************************/
#ifndef __H_BENCHMARK__
#define __H_BENCHMARK__
/************************************************************/
//includes
#include <windows.h>
#include <cstdio>
#include <ctime>
/************************************************************/
//type names
typedef unsigned long dword;
typedef unsigned long long qword;
/************************************************************/
//default test description
#define GENERIC_TEST "Generic Test"
/************************************************************/
//for use with SET_ENVIRONMENT - see below
#define CLEAN true
#define DIRTY false
/************************************************************/
//benchmark setup data - don`t access the members
//directly, use helper macro setters defined below
struct params_t
{
char* description;
bool can_set_ip_flag;
bool clean_environment;
int testing_iterations;
int caching_iterations;
qword code_block_time_A;
qword code_block_time_B;
qword bechmark_time_offset;
};
/************************************************************/
//parameters - all tests use this instance !!!
extern params_t params;
/************************************************************/
//functions
bool Setup(int argc, char* argv[]);
void Close();
int AssertCPU(); //can CPU run this app ???
void Calibrate(); //get benchmark time offset
bool CanManipulateIP(); //can we access the IP flag ???
void RestoreEnvironment(); //switch interrupts on
void SetCleanEnvironment(); //switch interrupts off
void Print(const char*, ...); //prints to stdout & log
void PrintTestSummary(); //prints test summary to stdout & log
void PrintHelp(); //prints help to stdout
/************************************************************/
//timer
#ifdef _MSC_VER
#define CLOCK(var) \
__asm{ \
__asm xor eax, eax \
__asm cpuid \
__asm rdtsc \
__asm mov dword ptr [(var)], eax \
__asm mov dword ptr [(var)+4], edx \
}
#else
#error VC++ environment required
//may put code for other platforms
#endif //_MSC_VER
/************************************************************/
//application frame
#define START_BENCHMARK \
int _i, _q; \
qword _b1, _e1, _b2, _e2; \
int main(int argc, char* argv[]) \
{ \
if(!Setup(argc, argv)) \
return -1;
#define CLOSE_BENCHMARK \
Close(); \
system("pause"); \
return 0; \
}
/************************************************************/
//code caching
#define BEGIN_CACHING \
for(_q = 0; _q < params.caching_iterations;_q++) \
{
#define FINISH_CACHING \
}
/************************************************************/
//code testing
#define EXEBLOCK_A \
SetCleanEnvironment(); \
params.code_block_time_A=0xffffffffffffffff; \
params.code_block_time_B=0xffffffffffffffff; \
for(_i = 0; _i < params.testing_iterations;_i++) \
{ \
CLOCK(_b1);
#define EXEBLOCK_B \
CLOCK(_e1); \
CLOCK(_b2);
#define EVALUATE \
CLOCK(_e2); \
qword _d1 = _e1 - _b1; \
qword _d2 = _e2 - _b2; \
if(_d1 < params.code_block_time_A) \
params.code_block_time_A = _d1; \
if(_d2 < params.code_block_time_B) \
params.code_block_time_B = _d2; \
} \
RestoreEnvironment(); \
PrintTestSummary();
/************************************************************/
//helper macros providing safe access to public data
//members - each parameter once set is valid for all
//consecutive tests until changed by a call to it`s
//appropriate setter
#define SET_DESCRIPTION(d) params.description = (d);
#define SET_ENVIRONMENT(e) params.clean_environment = (e);
#define SET_CACHING_ITERATIONS(n) params.caching_iterations = (n);
#define SET_TESTING_ITERATIONS(n) params.testing_iterations = (n);
/************************************************************/
#endif // __H_BENCHMARK__
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.