⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memorytestimpl.cpp

📁 获得多核硬件所有的相关信息。汇编源代码。Visual Studio2003、2005环境皆可。速度快。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//---------------------------------------------------------------------------
//
// MemoryTestImpl.cpp: CMemoryTest Class Implementation
//
//---------------------------------------------------------------------------

#include "StdAfx.h"
#include "MemoryTestImpl.h"

const char* szTestNames[] =
{
    "Microarchitecture - Memory Bandwidth",
    "Microarchitecture - D-Cache Latency",
    "Microarchitecture - Memory Walk",
    "Microarchitecture - D-Cache Bandwidth",
    "Microarchitecture - D-Cache Arrival",
    "Microarchitecture - Decode Bandwidth",
    "Microarchitecture - I-Cache Latency",
    "Microarchitecture - I-ROB",
    "Microarchitecture - D-TLB",
    "Microarchitecture - I-TLB",
    "RAM Performance - Stream",
    "RAM Performance - Checksum",
    "RAM Performance - Substring Search",
    "RAM Stability"
};

// Thread and event handles
HANDLE hThread[32];

// Default thread function
DWORD WINAPI ThreadFunc(void* lpParam)
{
    // Wait for the exit condition
    while (WaitForSingleObject(hThread[0], 0) != WAIT_OBJECT_0)
    {
        __asm pause;
    }

    // Exit the thread
    return 0;
}

// Message queue processing
void __fastcall CMemoryTest::ProcessMessages()
{
    MSG msg;
    while (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        if (msg.message == WM_QUIT)
        {
            break;
        }
        if (msg.message == WM_SIZE)
        {
            Graph.Resize();
        }
        if (msg.message == WM_KEYDOWN)
        {
            if (msg.wParam == VK_ESCAPE)
            {
                IsTerminatePending = true;
            }
        }
        ::TranslateMessage(&msg);
        ::DispatchMessage(&msg);
    }
}

// Log file output
void __fastcall CMemoryTest::UpdateLogFile(char* pString)
{
    FILE* fp = fopen("stability.log", "at");
    if (fp)
    {
        fputs(pString, fp);
        fclose(fp);
    }
}

//***************************************************************************
//   LoggedSetLockPagesPrivilege: a function to obtain, if possible, or
//   release the privilege of locking physical pages.
//
//   Inputs:
//
//       HANDLE hProcess: Handle for the process for which the
//       privilege is needed
//
//       BOOL bEnable: Enable (TRUE) or disable?
//
//   Return value: TRUE indicates success, FALSE failure.
//
//***************************************************************************
BOOL __fastcall CMemoryTest::LoggedSetLockPagesPrivilege(HANDLE hProcess, BOOL bEnable, char* pError)
{
    struct
    {
        DWORD Count;
        LUID_AND_ATTRIBUTES Privilege[1];
    } Info;

    HANDLE Token;
    BOOL Result;

    // Runtime link to ADVAPI32.DLL
    PTOpenProcessToken OpenProcessToken = 
    (PTOpenProcessToken)::GetProcAddress(::GetModuleHandle("advapi32"), "OpenProcessToken");

    if (! OpenProcessToken)
    {
        if (pError) strcpy(pError, "OpenProcessToken() entry point not found (no OS support).");
        return FALSE;
    }

    // @WARNING: explicitly using ANSI version
    PTLookupPrivilegeValue LookupPrivilegeValue =
    (PTLookupPrivilegeValue)::GetProcAddress(::GetModuleHandle("advapi32"), "LookupPrivilegeValueA");

    if (! LookupPrivilegeValue)
    {
        if (pError) strcpy(pError, "LookupPrivilegeValue() entry point not found (no OS support).");
        return FALSE;
    }

    PTAdjustTokenPrivileges AdjustTokenPrivileges =
    (PTAdjustTokenPrivileges)::GetProcAddress(::GetModuleHandle("advapi32"), "AdjustTokenPrivileges");
    
    if (! AdjustTokenPrivileges)
    {
        if (pError) strcpy(pError, "AdjustTokenPrivileges() entry point not found (no OS support).");
        return FALSE;
    }

    // Open the token.
    Result = OpenProcessToken(hProcess,
                              TOKEN_ADJUST_PRIVILEGES,
                              &Token);

    if (Result != TRUE)
    {
        if (pError) strcpy(pError, "Cannot open process token.");
        return FALSE;
    }

    // Enable or disable?
    Info.Count = 1;
    if (bEnable)
    {
        Info.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
    }
    else 
    {
        Info.Privilege[0].Attributes = 0;
    }

    // Get the LUID.
    Result = LookupPrivilegeValue(NULL,
                                  SE_LOCK_MEMORY_NAME,
                                  &(Info.Privilege[0].Luid));

    if (Result != TRUE)
    {
        if (pError) sprintf(pError, "Cannot get privilege value for %s.", SE_LOCK_MEMORY_NAME);
        return FALSE;
    }

    // Adjust the privilege.
    Result = AdjustTokenPrivileges(Token, FALSE,
                                   (PTOKEN_PRIVILEGES)&Info,
                                   NULL, NULL, NULL);

    // Check the result.
    if (Result != TRUE)
    {
        if (pError) sprintf(pError, "Cannot adjust token privileges, error %u.", ::GetLastError());
        return FALSE;
    }
    else
    {
        if (::GetLastError() != ERROR_SUCCESS)
        {
            if (pError) strcpy(pError, "Cannot enable SE_LOCK_MEMORY privilege, please check the local policy.");
            return FALSE;
        }
    }

    ::CloseHandle(Token);

    return TRUE;
}

void __fastcall CMemoryTest::SetBlockPointers(DWORD SegmentsCount)
{
    // Finding the closest 1MB offset for each segment
    DWORD off;

    if (SegmentsCount <= 2)
    {
        off = MAX_MEMORY_BLOCK_SIZE >> 1;
    }
    else if (SegmentsCount <= 4)
    {
        off = MAX_MEMORY_BLOCK_SIZE >> 2;
    }
    else if (SegmentsCount <= 8)
    {
        off = MAX_MEMORY_BLOCK_SIZE >> 3;
    }
    else if (SegmentsCount <= 16)
    {
        off = MAX_MEMORY_BLOCK_SIZE >> 4;
    }
    else if (SegmentsCount <= 32)
    {
        off = MAX_MEMORY_BLOCK_SIZE >> 5;
    }
    else
    {
        off = MAX_MEMORY_BLOCK_SIZE >> 6;
    }

    for (DWORD l = 1; l < SegmentsCount; ++l)
    {
        ptr[l] = (DWORD *)(DWORD(ptr[l - 1]) + off);
    }
}

void __fastcall CMemoryTest::SetMemoryFunc(DWORD PrefetchDistance)
{
    switch (TestData.RegisterType)
    {
    case RT_64_BIT_MMX:
    {
        WriteMem = (TestData.UseNonTemporalStore) ?
                   &WriteMMX_NT :
                   &WriteMMX;

        if ((PrefetchDistance > 0) ||
            (TestData.PrefetchType == PT_BLOCK_PREFETCH_1) ||
            (TestData.PrefetchType == PT_BLOCK_PREFETCH_2))
        {
            switch (TestData.PrefetchType)
            {
            case PT_PREFETCHNTA:
            {
                switch (TestData.LogStrideSize[0])
                {
                case 4:
                    ReadMem = &ReadMMX_PFNTA_16;
                    CopyMem = (TestData.UseNonTemporalStore) ?
                              &CopyMMX_PFNTA_16_NT :
                              &CopyMMX_PFNTA_16;
                    break;
                case 5:
                    ReadMem = &ReadMMX_PFNTA_32;
                    CopyMem = (TestData.UseNonTemporalStore) ?
                              &CopyMMX_PFNTA_32_NT :
                              &CopyMMX_PFNTA_32;
                    break;
                case 6:
                default:
                    ReadMem = &ReadMMX_PFNTA_64;
                    CopyMem = (TestData.UseNonTemporalStore) ?
                              &CopyMMX_PFNTA_64_NT :
                              &CopyMMX_PFNTA_64;
                    break;
                case 7:
                    ReadMem = &ReadMMX_PFNTA_128;
                    CopyMem = (TestData.UseNonTemporalStore) ?
                              &CopyMMX_PFNTA_128_NT :
                              &CopyMMX_PFNTA_128;
                    break;
                case 8:
                    ReadMem = &ReadMMX_PFNTA_256;
                    CopyMem = (TestData.UseNonTemporalStore) ?
                              &CopyMMX_PFNTA_256_NT :
                              &CopyMMX_PFNTA_256;
                    break;
                case 9:
                    ReadMem = &ReadMMX_PFNTA_512;
                    CopyMem = (TestData.UseNonTemporalStore) ?
                              &CopyMMX_PFNTA_512_NT :
                              &CopyMMX_PFNTA_512;
                    break;
                }
                break;
            }
            case PT_PREFETCHT0:
            {
                switch (TestData.LogStrideSize[0])
                {
                case 4:
                    ReadMem = &ReadMMX_PFT0_16;
                    CopyMem = (TestData.UseNonTemporalStore) ?
                              &CopyMMX_PFT0_16_NT :
                              &CopyMMX_PFT0_16;
                    break;
                case 5:
                    ReadMem = &ReadMMX_PFT0_32;
                    CopyMem = (TestData.UseNonTemporalStore) ?
                              &CopyMMX_PFT0_32_NT :
                              &CopyMMX_PFT0_32;
                    break;
                case 6:
                default:
                    ReadMem = &ReadMMX_PFT0_64;
                    CopyMem = (TestData.UseNonTemporalStore) ?
                              &CopyMMX_PFT0_64_NT :
                              &CopyMMX_PFT0_64;
                    break;
                case 7:
                    ReadMem = &ReadMMX_PFT0_128;
                    CopyMem = (TestData.UseNonTemporalStore) ?
                              &CopyMMX_PFT0_128_NT :
                              &CopyMMX_PFT0_128;
                    break;
                case 8:
                    ReadMem = &ReadMMX_PFT0_256;
                    CopyMem = (TestData.UseNonTemporalStore) ?
                              &CopyMMX_PFT0_256_NT :
                              &CopyMMX_PFT0_256;
                    break;
                case 9:
                    ReadMem = &ReadMMX_PFT0_512;
                    CopyMem = (TestData.UseNonTemporalStore) ?
                              &CopyMMX_PFT0_512_NT :
                              &CopyMMX_PFT0_512;
                    break;
                }
                break;
            }
            case PT_PREFETCHT1:
            {
                switch (TestData.LogStrideSize[0])
                {
                case 4:
                    ReadMem = &ReadMMX_PFT1_16;
                    CopyMem = (TestData.UseNonTemporalStore) ?
                              &CopyMMX_PFT1_16_NT :
                              &CopyMMX_PFT1_16;
                    break;
                case 5:
                    ReadMem = &ReadMMX_PFT1_32;
                    CopyMem = (TestData.UseNonTemporalStore) ?
                              &CopyMMX_PFT1_32_NT :
                              &CopyMMX_PFT1_32;
                    break;
                case 6:
                default:
                    ReadMem = &ReadMMX_PFT1_64;
                    CopyMem = (TestData.UseNonTemporalStore) ?
                              &CopyMMX_PFT1_64_NT :
                              &CopyMMX_PFT1_64;
                    break;
                case 7:
                    ReadMem = &ReadMMX_PFT1_128;
                    CopyMem = (TestData.UseNonTemporalStore) ?
                              &CopyMMX_PFT1_128_NT :
                              &CopyMMX_PFT1_128;
                    break;
                case 8:
                    ReadMem = &ReadMMX_PFT1_256;
                    CopyMem = (TestData.UseNonTemporalStore) ?
                              &CopyMMX_PFT1_256_NT :
                              &CopyMMX_PFT1_256;
                    break;
                case 9:
                    ReadMem = &ReadMMX_PFT1_512;
                    CopyMem = (TestData.UseNonTemporalStore) ?
                              &CopyMMX_PFT1_512_NT :
                              &CopyMMX_PFT1_512;
                    break;
                }
                break;
            }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -