28

I'd like my program to read the cache line size of the CPU it's running on in C++.

I know that this can't be done portably, so I will need a solution for Linux and another for Windows (Solutions for other systems could be usefull to others, so post them if you know them).

For Linux I could read the content of /proc/cpuinfo and parse the line begining with cache_alignment. Maybe there is a better way involving a call to an API.

For Windows I simply have no idea.

tshepang
  • 11,360
  • 21
  • 88
  • 132
Mathieu Pagé
  • 10,144
  • 12
  • 47
  • 71

7 Answers7

19

On Win32, GetLogicalProcessorInformation will give you back a SYSTEM_LOGICAL_PROCESSOR_INFORMATION which contains a CACHE_DESCRIPTOR, which has the information you need.

Roger Lipscombe
  • 85,268
  • 51
  • 226
  • 362
Nick
  • 13,072
  • 15
  • 62
  • 98
5

On Linux try the proccpuinfo library, an architecture independent C API for reading /proc/cpuinfo

PiedPiper
  • 5,557
  • 1
  • 29
  • 40
4

For x86, the CPUID instruction. A quick google search reveals some libraries for win32 and c++. I have used CPUID via inline assembler as well.

Some more info:

robottobor
  • 11,204
  • 10
  • 38
  • 36
3

Looks like at least SCO unix (http://uw714doc.sco.com/en/man/html.3C/sysconf.3C.html) has _SC_CACHE_LINE for sysconf. Perhaps other platforms have something similar?

Evan Teran
  • 84,149
  • 29
  • 174
  • 237
3

On Windows

#include <Windows.h>
#include <iostream>

using std::cout; using std::endl;

int main()
{
    SYSTEM_INFO systemInfo;
    GetSystemInfo(&systemInfo);
    cout << "Page Size Is: " << systemInfo.dwPageSize;
    getchar();
}

On Linux

http://linux.die.net/man/2/getpagesize

Researcher
  • 946
  • 6
  • 13
  • 3
    After coming back to this I don't believe I answered your question, which was about the cache line size rather then the memory page size correct? https://en.wikipedia.org/wiki/Page_(computer_memory) I was googling for a page size snippet (working on a project involving memory access) and came here, the dangers of skimming. Please untick my answer, but probably worth leaving it here for future reference. – Researcher Sep 15 '16 at 17:33
2

Here is sample code for those who wonder how to to utilize the function in accepted answer:

#include <new>
#include <iostream>
#include <Windows.h>


void ShowCacheSize()
{
    using CPUInfo = SYSTEM_LOGICAL_PROCESSOR_INFORMATION;
    DWORD len = 0;
    CPUInfo* buffer = nullptr;

    // Determine required length of a buffer
    if ((GetLogicalProcessorInformation(buffer, &len) == FALSE) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER))
    {
        // Allocate buffer of required size
        buffer = new (std::nothrow) CPUInfo[len]{ };

        if (buffer == nullptr)
        {
            std::cout << "Buffer allocation of " << len << " bytes failed" << std::endl;
        }
        else if (GetLogicalProcessorInformation(buffer, &len) != FALSE)
        {
            for (DWORD i = 0; i < len; ++i)
            {
                // This will be true for multiple returned caches, we need just one
                if (buffer[i].Relationship == RelationCache)
                {
                    std::cout << "Cache line size is: " << buffer[i].Cache.LineSize << " bytes" << std::endl;
                    break;
                }
            }
        }
        else
        {
            std::cout << "ERROR: " << GetLastError() << std::endl;
        }

        delete[] buffer;
    }
}
metablaster
  • 1,585
  • 7
  • 18
  • If `len` is in bytes, shouldn't it be divided by `sizeof(CPUInfo)` before running through the buffer entries? – GuillemVS Jan 15 '22 at 21:35
0

I think you need NtQuerySystemInformation from ntdll.dll.

rami
  • 1,586
  • 12
  • 13