目的
1、 采用动态分配内存的方式进行测试,要求内存拷贝的操作时间不能超过500ms;连续内存拷贝耗时超过300ms的连续次数不能超过3次;
2、 测试需要覆盖从小块内存的拷贝到大块内存的申请和拷贝的情况;
3、 测试过程中需要考虑系统内存负荷达到百分之80的情况;
#include "Stdafx.h"
#include <iostream>
#include <sstream>
#include <fstream>
#include <stdint.h>
#include "Markup.h"
#include "ipp/ipp.h"
#include <string>
#include <time.h>
#include <vector>
#include <boost/format.hpp>
#include <boost/tokenizer.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/algorithm/string.hpp>
#define time_shift (uint64_t)116444736000000000ULL // (27111902 << 32) + 3577643008
using namespace std;
char filename[60]="";
char reportFilename[60]="";
int iAllLoopCount=0;//总循环次数
double dNewThreshold,d4KThreshold,dMemsetThreshold,dMemcpyThreshold;
class TmePerofrmanceCount
{
public:
static LARGE_INTEGER StartTiming();
static double EndTiming(LARGE_INTEGER &nStartTime);
static int64_t m_nCPUFreq;
};
struct TestItem
{
int64_t iSize;
int iLoopCount;
int iAllLoopCount;
double dOrgMem;
int iInitType;
};
int64_t TmePerofrmanceCount::m_nCPUFreq = 0;
LARGE_INTEGER TmePerofrmanceCount::StartTiming()
{
LARGE_INTEGER nFreq;
::QueryPerformanceFrequency(&nFreq);
m_nCPUFreq = nFreq.QuadPart;
LARGE_INTEGER nStartTime;
::QueryPerformanceCounter(&nStartTime);
return nStartTime;
}
double TmePerofrmanceCount::EndTiming(LARGE_INTEGER &nStartTime)
{
LARGE_INTEGER nEndTime;
::QueryPerformanceCounter(&nEndTime);
return 1000*(nEndTime.QuadPart-nStartTime.QuadPart)/(double)m_nCPUFreq;
}
void SetProcessPriority()
{
HANDLE hPS = ::OpenProcess( PROCESS_ALL_ACCESS, false, ::GetCurrentProcessId() );
BOOL bSetRealTimeRet = ::SetPriorityClass( hPS, REALTIME_PRIORITY_CLASS );
if (!bSetRealTimeRet)
{
if (INVALID_HANDLE_VALUE != hPS)
{
if (!::SetPriorityClass( hPS, REALTIME_PRIORITY_CLASS ))
{
throw std::logic_error("Set RDM REALTIME failed.");
}
}
}
::CloseHandle( hPS );
}
void ReconMemSet(char *pDataPointer, int64_t &iMemSize)
{
int64_t i4K = 4096;
int64_t iCurPos = 512;
do
{
*(pDataPointer+iCurPos) = 100;
iCurPos += i4K;
} while (iCurPos < iMemSize);
}
void RDMTestLog(std::string &strContent,const char* filename)
{
{
FILETIME ft;
GetSystemTimeAsFileTime(&ft);
union {
FILETIME as_file_time;
uint64_t as_integer;
} time_caster;
time_caster.as_file_time = ft;
time_caster.as_integer -= time_shift;
uint64_t iTempValue = time_caster.as_integer/10000UL;
std::ofstream f1(filename, std::ios::out|std::ios::app);
f1 <<strContent.c_str();
f1.flush();
f1.close();
}
}
void memcpytest(struct TestItem &OneTest)
{
int64_t i1024 = 1024;
int64_t iSizeOrg;
std::stringstream sssLog;
double dMemsetavg = 0.0;
double dMaxTime=0.0,dMinTime=10000000.0,dAvgTime=0.0;
double dElapsed4k=0;
double dElapsedMemset=0;
int64_t iCpyLoopCount;
char *pdataCpy = new char[OneTest.iSize];
if(OneTest.dOrgMem<1&&OneTest.dOrgMem*1000>1)
{
iSizeOrg=i1024*i1024*OneTest.dOrgMem*1000;
}
else
iSizeOrg=i1024*i1024*i1024*OneTest.dOrgMem;
if(OneTest.iSize<0.0001)
{
return;
}
iCpyLoopCount = iSizeOrg/OneTest.iSize;
try
{
for (int i=0; i<OneTest.iSize; i++)
{
*(pdataCpy+i) = i%200;
}
for (int i=0; i<OneTest.iLoopCount; i++)
{
LARGE_INTEGER newStart = TmePerofrmanceCount::StartTiming();
char *pData = new char[iSizeOrg];
double dnewElapsed = TmePerofrmanceCount::EndTiming(newStart);
if(1==OneTest.iInitType)
{
LARGE_INTEGER Start4k = TmePerofrmanceCount::StartTiming();
ReconMemSet(pData, iSizeOrg);
dElapsed4k = TmePerofrmanceCount::EndTiming(Start4k);
}
else
{
if (2==OneTest.iInitType)
{
LARGE_INTEGER StartMemset = TmePerofrmanceCount::StartTiming();
memset(pData,0, iSizeOrg);
dElapsedMemset = TmePerofrmanceCount::EndTiming(StartMemset);
}
}
LARGE_INTEGER lgStartallcpy = TmePerofrmanceCount::StartTiming();
for (int j=0; j<iCpyLoopCount; j++)
{
LARGE_INTEGER lgStartcpy = TmePerofrmanceCount::StartTiming();
memcpy(pData+j*OneTest.iSize, pdataCpy, OneTest.iSize);
double dElapsedcpy = TmePerofrmanceCount::EndTiming(lgStartcpy);
if(dMaxTime<dElapsedcpy)
dMaxTime=dElapsedcpy;
if(dMinTime>dElapsedcpy)
dMinTime=dElapsedcpy;
dAvgTime+=dElapsedcpy;
}
dAvgTime=dAvgTime/iCpyLoopCount;
double dElapsedallcpy = TmePerofrmanceCount::EndTiming(lgStartallcpy);
dMemsetavg+=dElapsedallcpy;
sssLog<<iSizeOrg<<","<<OneTest.iSize<<","<<dnewElapsed<<","<<dElapsed4k<<","<<dElapsedMemset<<","<<dMaxTime<<","<<dMinTime<<","<<dAvgTime<<","
<<dElapsedallcpy<<","<<dMemsetavg/(i+1)<<"\n";
delete [] pData;
}
delete [] pdataCpy;
}
catch (std::exception &e)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
std::cout<<e.what() <<std::endl;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED |FOREGROUND_GREEN | FOREGROUND_BLUE);
throw;
}
RDMTestLog(sssLog.str(),filename);
}
bool GetParaFromXML(std::string strFilePath,std::string strParentElem,std::string& strValue)
{
CMarkup xmlDoc;
if (!xmlDoc.Load(strFilePath.c_str()))
{
return false;
}
if (xmlDoc.Load(strFilePath.c_str()))
{
xmlDoc.ResetMainPos();
while (xmlDoc.FindChildElem(strParentElem.c_str()))
{
strValue=xmlDoc.GetChildData();
break;
}
return true;
}
}
void FindError(vector <vector <string>> vecAll_stock,int iColNum,double dThreshold,string sTestItem)
{
std::stringstream reportLog;
string sTemp_size=vecAll_stock[1][0];
bool bTemp_result=true;
for (int i=1;i<vecAll_stock.size();i++)
{
if (0==strcmp(vecAll_stock[i][0].c_str(),sTemp_size.c_str()))
{
if (bTemp_result)
{
if (atof(vecAll_stock[i][iColNum].c_str())>dThreshold)
{
reportLog<<sTestItem<<" timeout found! Temp size is "<<vecAll_stock[i][0]<<". Threshold is "<<dThreshold<<"\n";
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
std::cout<<sTestItem<<" timeout found! Temp size is "<<vecAll_stock[i][0]<<". Threshold is "<<dThreshold<<"\n";
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED |FOREGROUND_GREEN | FOREGROUND_BLUE);
bTemp_result=false;
continue;
}
}
}
else
{
sTemp_size=vecAll_stock[i][0];
bTemp_result=true;
i--;
}
}
RDMTestLog(reportLog.str(),reportFilename);
}
void LogReport(double dNewThreshold,double d4KThreshold,double dMemsetThreshold,double dMemcpyThreshold)
{
int iItemSize=0;
vector <vector <string>> All_stock;
vector<string> stock_info;
string line_stock_info;
ifstream in_stock_info(filename);
if (in_stock_info.fail())
{
cout << "Open input file failed" <<endl;
}
while (getline(in_stock_info, line_stock_info) && in_stock_info.good())
{
if (""==line_stock_info)
continue;
boost::split(stock_info,line_stock_info, boost::is_any_of(","));
All_stock.push_back(stock_info);
}
FindError(All_stock,2,dNewThreshold,"New");
FindError(All_stock,3,d4KThreshold,"4Kmemset");
FindError(All_stock,4,dMemsetThreshold,"Memset");
FindError(All_stock,8,dMemcpyThreshold,"Memcpy");
}
bool ctrlhandler( DWORD fdwctrltype )
{
std::stringstream sssLog;
switch( fdwctrltype )
{
// handle the ctrl-c signal.
//case CTRL_C_EVENT:
// printf( "ctrl-c event\n\n" );
// return( true );
// ctrl-close: confirm that the user wants to exit.
case CTRL_CLOSE_EVENT:
LogReport(dNewThreshold,d4KThreshold,dMemsetThreshold,dMemcpyThreshold);
sssLog<<"Test Interrupt!!\n";
RDMTestLog(sssLog.str(),filename);
return( true );
// // pass other signals to the next handler.
//case CTRL_BREAK_EVENT:
// printf( "ctrl-break event\n\n" );
// return false;
//case CTRL_LOGOFF_EVENT:
// printf( "ctrl-logoff event\n\n" );
// return false;
//case CTRL_SHUTDOWN_EVENT:
// printf( "ctrl-shutdown event\n\n" );
// return false;
default:
return false;
}
}
class test
{
public:
bool itest;
int i;
};
int _tmain(int argc, _TCHAR* argv[])
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);
std::cout<<"******************ReconWorkstationMemoryTest*******************\n";
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED |FOREGROUND_GREEN | FOREGROUND_BLUE);
string strFilePath="MemoryTest.xml";
string strALC;
int64_t i1024 = 1024;
time_t timep;
time (&timep);
strftime(filename, sizeof(filename), "MemoryAccessorLog%Y%m%d%H%M%S.csv",localtime(&timep) );
strftime(reportFilename, sizeof(filename), "TestReport%Y%m%d%H%M%S.csv",localtime(&timep) );
std::stringstream sssLog;
std::stringstream reportLog;
if( SetConsoleCtrlHandler( (PHANDLER_ROUTINE) ctrlhandler, true ) )
{
sssLog<<"ALL_MemSize,OnePiece_MemSize,NEW_Time,4KMemset_Time,All0Memset_Time,OnePiece_Max_Time,OnePiece_Min_Time,OnePiece_Avg_Time,Memcpy_Time,Memcpy_Avg_Time\n";
//SetProcessPriority();
if(!GetParaFromXML(strFilePath,"AllLoopCount",strALC))
{
std::cout<<"xml file error!"<<"\n";
std::cin.get();
return 0;
}
else
{
iAllLoopCount=atoi(strALC.c_str());
}
if(!GetParaFromXML(strFilePath,"NewThreshold",strALC))
{
std::cout<<"xml file error!"<<"\n";
std::cin.get();
return 0;
}
else
{
dNewThreshold=atof(strALC.c_str());
}
if(!GetParaFromXML(strFilePath,"FourKThreshold",strALC))
{
std::cout<<"xml file error!"<<"\n";
std::cin.get();
return 0;
}
else
{
d4KThreshold=atof(strALC.c_str());
}
if(!GetParaFromXML(strFilePath,"MemsetThreshold",strALC))
{
std::cout<<"xml file error!"<<"\n";
std::cin.get();
return 0;
}
else
{
dMemsetThreshold=atof(strALC.c_str());
}
if(!GetParaFromXML(strFilePath,"MemcpyThreshold",strALC))
{
std::cout<<"xml file error!"<<"\n";
std::cin.get();
return 0;
}
else
{
dMemcpyThreshold=atof(strALC.c_str());
}
RDMTestLog(sssLog.str(),filename);
std::cout<<"----The test loop count is "<<iAllLoopCount<<"\n";
for(int i=0;i<iAllLoopCount;i++)
{
std::cout<<"Executing loop is "<<i+1<<"\n";
CMarkup xml;
if (!xml.Load(strFilePath.c_str()))
{
std::cout<<"xml file error!"<<"\n";
std::cin.get();
return 0;
}
xml.ResetPos();
if (xml.FindElem())
{
xml.IntoElem();
while(xml.FindElem())
{
if (strcmp(xml.GetTagName(),"List")==0)
{
xml.IntoElem();
while (xml.FindElem())
{
struct TestItem OneTest;
int64_t itmp;
OneTest.iAllLoopCount=iAllLoopCount;
if (strcmp(xml.GetTagName(),"Item")==0)
{
string fieldname = xml.GetAttrib("name");
if(atof(fieldname.c_str())<1&&atof(fieldname.c_str())*1000>1)
{
OneTest.iSize=i1024*atof(fieldname.c_str())*1000;
}
else
OneTest.iSize=i1024*i1024*atof(fieldname.c_str());
fieldname = xml.GetAttrib("type");
OneTest.iInitType=fieldname=="1"?1:(fieldname=="2"? 2:0);
fieldname = xml.GetAttrib("LoopCount");
OneTest.iLoopCount=atoi(fieldname.c_str());
fieldname = xml.GetAttrib("OrgMemory");
OneTest.dOrgMem=atof(fieldname.c_str());
}
try
{
memcpytest(OneTest);
}
catch(...)
{
reportLog<<"An Exception occured in test Size:"<<OneTest.dOrgMem<<"G, Piece:"<<OneTest.iSize<<"byte, Type:"<<OneTest.iInitType<<"\n";
continue;
}
}
xml.OutOfElem();
}
}
}
}
//find error info in log file
LogReport(dNewThreshold,d4KThreshold,dMemsetThreshold,dMemcpyThreshold);
cout << "ReconWorkstation Memory Test is Over!" <<endl;
return 0;
}
}
配置文件
<?xml version="1.0" encoding="utf-8"?>
<MemoryTest>
<List name="TestList">
<!--using 4k memset-->
<Item name="0.01" type="1" LoopCount="10" OrgMemory="0.02"/>
<Item name="0.02" type="1" LoopCount="10" OrgMemory="0.02"/>
<Item name="0.05" type="1" LoopCount="10" OrgMemory="0.02"/>
<Item name="0.1" type="1" LoopCount="10" OrgMemory="0.02"/>
<Item name="0.15" type="1" LoopCount="10" OrgMemory="0.02"/>
<Item name="0.2" type="1" LoopCount="10" OrgMemory="0.02"/>
<Item name="0.3" type="1" LoopCount="10" OrgMemory="0.02"/>
<Item name="0.5" type="1" LoopCount="10" OrgMemory="0.02"/>
<Item name="0.8" type="1" LoopCount="10" OrgMemory="0.02"/>
<Item name="1" type="1" LoopCount="10" OrgMemory="0.02"/>
</List>
<AllLoopCount>1</AllLoopCount>
<NewThreshold>0.01</NewThreshold>
<FourKThreshold>100</FourKThreshold>
<MemsetThreshold>200</MemsetThreshold>
<MemcpyThreshold>1000</MemcpyThreshold>
</MemoryTest>
记录一下~