📄 memorytestimpl.h
字号:
//---------------------------------------------------------------------------
//
// MemoryTestImpl.h: CMemoryTest Class Header
//
//---------------------------------------------------------------------------
#ifndef MemoryTestImplH
#define MemoryTestImplH
#include "MemoryTest.h"
#include "Misc.h"
#include "MemoryTestGraph.h"
#include "MMX64.h"
#include "SSE128.h"
#include "Latency.h"
#include "CacheBandwidth.h"
#include "Decode.h"
#include "Stream.h"
#include "Checksum.h"
#include "SubString.h"
// Assumed L1/L2 boundaries
const DWORD POST_L1_REGION = 96 << 10; // 96K
const DWORD POST_L2_REGION = 32 << 20; // 32M
const DWORD DEF_LOG_CL_SIZE = 6; // 64 bytes
const DWORD MAX_MEMORY_RESERVED_SIZE = MAX_MEMORY_BLOCK_SIZE;
const DWORD MAX_SEGMENTS_COUNT = 64;
const DWORD MAX_ARRAY_POINTS = 1048576;
const DWORD MAX_MAJOR_POINTS = 25;
const DWORD MAX_TESTS = 4; // up to 4 subtests per each test
const DWORD DEF_SLEEP_TIME = 10; // ms
// Pen width and colors
const DWORD DEF_PEN_WIDTH = 2;
const COLORREF PEN_COLOR_LINES = RGB(128, 128, 128);
const COLORREF PEN_COLOR_READ_BANDWIDTH = RGB(255, 0, 0);
const COLORREF PEN_COLOR_WRITE_BANDWIDTH = RGB(0, 255, 0);
const COLORREF PEN_COLOR_COPY_BANDWIDTH = RGB(255, 255, 0);
const COLORREF PEN_COLOR_FORWARD_LATENCY = RGB(255, 0, 255);
const COLORREF PEN_COLOR_BACKWARD_LATENCY = RGB(0, 255, 255);
const COLORREF PEN_COLOR_RANDOM_LATENCY = RGB(0, 0, 255);
const COLORREF PEN_COLOR_PSEUDORANDOM_LATENCY = RGB(0, 255, 0);
const COLORREF PEN_COLOR_FORWARD_READ = RGB(255, 0, 255);
const COLORREF PEN_COLOR_BACKWARD_READ = RGB(0, 255, 255);
const COLORREF PEN_COLOR_FORWARD_WRITE = RGB(255, 0, 0);
const COLORREF PEN_COLOR_BACKWARD_WRITE = RGB(0, 255, 0);
const COLORREF PEN_COLOR_DECODE_BANDWIDTH = RGB(255, 0, 0);
const COLORREF PEN_COLOR_FP_COPY = RGB(255, 255, 0);
const COLORREF PEN_COLOR_FP_SCALE = RGB(255, 0, 0);
const COLORREF PEN_COLOR_FP_ADD = RGB(0, 255, 0);
const COLORREF PEN_COLOR_FP_TRIAD = RGB(0, 255, 255);
const COLORREF PEN_COLOR_CRC32 = RGB(255, 0, 0);
const COLORREF PEN_COLOR_ADLER32 = RGB(0, 255, 0);
const COLORREF PEN_COLOR_SUBSTRING_CS = RGB(255, 0, 0);
const COLORREF PEN_COLOR_SUBSTRING_CI = RGB(0, 255, 0);
DWORD WINAPI ThreadFunc(void* lpParam);
// AWE and security functions, Windows 2000/XP/2003 Server specific
typedef BOOL (WINAPI *PTAllocateUserPhysicalPages)(HANDLE hProcess, PULONG_PTR NumberOfPages, PULONG_PTR UserPfnArray);
typedef BOOL (WINAPI *PTMapUserPhysicalPages)(PVOID lpAddress, ULONG_PTR NumberOfPages, PULONG_PTR UserPfnArray);
typedef BOOL (WINAPI *PTFreeUserPhysicalPages)(HANDLE hProcess, PULONG_PTR NumberOfPages, PULONG_PTR UserPfnArray);
typedef BOOL (WINAPI *PTOpenProcessToken)(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle);
typedef BOOL (WINAPI *PTLookupPrivilegeValue)(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid);
typedef BOOL (WINAPI *PTAdjustTokenPrivileges)(HANDLE TokenHandle, BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength);
class CMemoryTest: public CAbsMemoryTest
{
private:
BOOL __fastcall LoggedSetLockPagesPrivilege(HANDLE hProcess, BOOL bEnable, char* pError);
void __fastcall ProcessMessages();
void __fastcall UpdateLogFile(char* pString);
void __fastcall CleanUp();
void __fastcall SetBlockPointers(DWORD SegmentsCount);
void __fastcall SetMemoryFunc(DWORD PrefetchDistance);
void __fastcall SetCacheBandwidthFunc(DWORD LogStrideSize);
void __fastcall MeasureNopLatency(LATENCYMEASUREMENT lm);
void __fastcall UpdateGraph();
HRESULT __fastcall Measure(MEASUREMENTDATA& md);
// Input data
TESTDATA TestData;
// AWE data
SYSTEM_INFO sSysInfo; // useful system information
ULONG_PTR NumberOfPages; // number of pages to request
ULONG_PTR NumberOfPagesInitial; // initial number of pages requested
ULONG_PTR *aPFNs; // page info; holds opaque data
LPVOID lpMemReserved; // AWE window
int PFNArraySize; // memory to request for PFN array
// Process Working Set Size data
DWORD dwMinimumWorkingSetSize;
DWORD dwMaximumWorkingSetSize;
// Intermediate data
char CpuDesc[80], CpuModel[60], CpuCore[20];
char RamDesc[80], RamType[40];
DWORD* ptr[MAX_SEGMENTS_COUNT]; // pointers to the block fragments
int arrData[MAX_ARRAY_POINTS]; // random access array data
GRAPHDATA GraphData[MAX_TESTS][MAX_POINTS]; // test data
DWORD sizeVal[MAX_POINTS];
int xMainVal[MAX_MAJOR_POINTS];
int yMainVal[MAX_MAJOR_POINTS];
double CpuFrequency; // CPU frequency
double MemoryFrequency; // RAM frequency
DWORD MemoryTimings[4]; // tCL-tRCD-tRP-tRAS
double NopLatency; // "nop" command execution latency
DWORD SerializeLatency; // latency of "serialization" with CPUID
DWORD LogCLSize[2]; // detected cache line size of each level
float yMax;
int NumPoints[MAX_TESTS]; // current points count for each test
int NumTestPoints; // total points count
DWORD MinSize; // closest Min Block Size, a power of two
DWORD MaxSize; // closest Max Block Size, a power of two
DWORD NumMajorPoints; // number of major points on a graph
DWORD MajorPointShift; // major point shift factor
DWORD MinIncrementUnit; // minimal allowed size increment, bytes
BOOL IsWrapAround; // graph data wraps around?
BOOL IsUpdateNeeded; // should we update random data array?
BOOL IsTerminatePending; // should we terminate?
// Memory access function pointers
void (__cdecl *ReadMem)(void* src, DWORD size, DWORD distance, DWORD repeat);
void (__cdecl *WriteMem)(void* dst, DWORD size, DWORD distance, DWORD repeat);
void (__cdecl *CopyMem)(void* dst, void* src, DWORD size, DWORD distance, DWORD repeat);
// Cache line read/write function pointers
void (__cdecl *ReadCacheLineFwd)(void* src, DWORD size, DWORD repeat);
void (__cdecl *WriteCacheLineFwd)(void* dst, DWORD size, DWORD repeat);
void (__cdecl *ReadCacheLineBwd)(void* src, DWORD size, DWORD repeat);
void (__cdecl *WriteCacheLineBwd)(void* dst, DWORD size, DWORD repeat);
// Decode bandwidth function pointer
void (__cdecl *CodeBlock)();
CLatencyFunc LatencyFunc; // Latency Functions
CMemoryTestGraph Graph; // MemoryTestGraph object
public:
CMemoryTest()
{
// Clean up pointers
ReadMem = NULL;
WriteMem = NULL;
CopyMem = NULL;
ReadCacheLineFwd = NULL;
WriteCacheLineFwd = NULL;
ReadCacheLineBwd = NULL;
WriteCacheLineBwd = NULL;
CodeBlock = NULL;
CpuDesc[0] = '\0';
RamDesc[0] = '\0';
CpuModel[0] = '\0';
CpuCore[0] = '\0';
RamType[0] = '\0';
CpuFrequency = 1.0; // default, to prevent div by 0
MemoryFrequency = 1.0;
MemoryTimings[0] = 0;
MemoryTimings[1] = 0;
MemoryTimings[2] = 0;
MemoryTimings[3] = 0;
__int64 c0 = ReadTSC();
__int64 c1 = ReadTSC();
SerializeLatency = DWORD(c1 - c0);
NopLatency = 0.0;
LogCLSize[0] = DEF_LOG_CL_SIZE; // default L1 cache line size
LogCLSize[1] = DEF_LOG_CL_SIZE; // default L2 cache line size
IsTerminatePending = false;
RANDOM_INIT;
}
HRESULT __stdcall GetNopLatency(double* pdNopLatency)
{
*pdNopLatency = NopLatency;
return S_OK;
}
HRESULT __stdcall SetNopLatency(double dNopLatency)
{
NopLatency = dNopLatency;
return S_OK;
}
HRESULT __stdcall GetCacheLineSize(DWORD dwLevel, DWORD* pLineSize)
{
*pLineSize = LogCLSize[dwLevel];
return S_OK;
}
HRESULT __stdcall SetCacheLineSize(DWORD dwLevel, DWORD dwLineSize)
{
LogCLSize[dwLevel] = dwLineSize;
return S_OK;
}
HRESULT __stdcall GetCpuModelData(LPSTR szModel, LPSTR szCore)
{
strncpy(szModel, CpuModel, sizeof(CpuModel));
strncpy(szCore, CpuCore, sizeof(CpuCore));
return S_OK;
}
HRESULT __stdcall SetCpuModelData(LPCSTR szModel, LPCSTR szCore)
{
strncpy(CpuModel, szModel, sizeof(CpuModel));
strncpy(CpuCore, szCore, sizeof(CpuCore));
return S_OK;
}
HRESULT __stdcall GetCpuFrequencyData(double* freq)
{
*freq = CpuFrequency * 1.0e+6;
return S_OK;
}
HRESULT __stdcall SetCpuFrequencyData(double freq)
{
CpuFrequency = freq * 1.0e-6; // in MHz
return S_OK;
}
HRESULT __stdcall GetMemoryTypeData(LPSTR szType)
{
strncpy(szType, RamType, sizeof(RamType));
return S_OK;
}
HRESULT __stdcall SetMemoryTypeData(LPCSTR szType)
{
strncpy(RamType, szType, sizeof(RamType));
return S_OK;
}
HRESULT __stdcall SetMemoryTimingsData(DWORD tCL, DWORD tRCD, DWORD tRP, DWORD tRAS)
{
MemoryTimings[0] = tCL;
MemoryTimings[1] = tRCD;
MemoryTimings[2] = tRP;
MemoryTimings[3] = tRAS;
return S_OK;
}
HRESULT __stdcall GetMemoryTimingsData(DWORD* tCL, DWORD* tRCD, DWORD* tRP, DWORD* tRAS)
{
*tCL = MemoryTimings[0];
*tRCD = MemoryTimings[1];
*tRP = MemoryTimings[2];
*tRAS = MemoryTimings[3];
return S_OK;
}
HRESULT __stdcall SetMemoryFrequencyData(double freq)
{
MemoryFrequency = freq;
return S_OK;
}
HRESULT __stdcall GetMemoryFrequencyData(double* freq)
{
*freq = MemoryFrequency;
return S_OK;
}
HRESULT __stdcall MeasureCacheLineSize(DWORD dwLevel);
HRESULT __stdcall CreateBMPFile(LPCSTR pszFile)
{
return Graph.CreateBMPFile(pszFile);
}
HRESULT __stdcall Initialize(MEMORYALLOCATION memAlloc, char* pError);
HRESULT __stdcall Connect(HWND hWnd)
{
return Graph.Connect(hWnd);
}
HRESULT __stdcall SetPriority(DWORD dwCpuIndex);
HRESULT __stdcall Lock(DWORD dwCpuIndex);
HRESULT __stdcall SetData(TESTDATA* pTD);
HRESULT __stdcall RunTest();
HRESULT __stdcall ShowGraph()
{
UpdateGraph();
return S_OK;
}
HRESULT __stdcall PaintGraph()
{
Graph.Paint();
return S_OK;
}
HRESULT __stdcall GetResults(TESTRESULTS* pTR, DWORD dwTestNum);
HRESULT __stdcall SetResults(TESTRESULTS* pTR, DWORD dwTestNum);
HRESULT __stdcall Unlock();
HRESULT __stdcall ResetPriority();
HRESULT __stdcall Disconnect()
{
return Graph.Disconnect();
}
HRESULT __stdcall Terminate(MEMORYALLOCATION memAlloc, char* pError);
};
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -