C++ 测试内存申请速度的小工具

目的

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>

记录一下~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值