I have done a simpler version of this before. I have not worked with Cache Affinity or counts, but I have queried cache size and cache line size. I suspect that the information can be gotten by swapping out a few argument in what I have done.
Here is what I did to get the size of the largest CPU cache on common PC platforms. I have run this on windows(msvc, mingw), Linux(gcc, clang) and Mac OS X (gcc) where it compiles and runs without warning, except some seemingly spurious warnings from msvc. This code comes from https://github.com/BlackToppStudios/DAGFrameScheduler/blob/master/src/systemcalls.cpp , but feel free to use this function for your own purposes (I am author/owner and I can relicense it out of GPL).
It checks if an L4 cache exists, if so it returns it. Then it checks if an L3 cache exists, if so it returns it and then L2 and L1 likewise.
This code expects _MEZZ_THREAD_WIN32_ to be defined only on windows, _MEZZ_THREAD_APPLE_ only on Mac OS X, and presumes Linux/BSD otherwise. MinGW has issues doing this as of 6 weeks before this writing, it might be possible to use msvc/windows sdk headers and c library, but I have not attempted that, it seemed to messy.
#ifdef _MEZZ_THREAD_WIN32_
#include <windows.h>
#else
#ifdef _MEZZ_THREAD_APPLE_
#include <sys/sysctl.h>
#endif
#include <sys/time.h>
#include <unistd.h>
#endif
typedef unsigned int Whole
Whole GetCacheSize()
{
#ifdef _MEZZ_THREAD_WIN32_
#ifdef _MSC_VER
size_t Size = 0;
DWORD buffer_size = 0;
DWORD i = 0;
SYSTEM_LOGICAL_PROCESSOR_INFORMATION * buffer = 0;
GetLogicalProcessorInformation(0, &buffer_size);
buffer = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION *)malloc(buffer_size);
GetLogicalProcessorInformation(&buffer[0], &buffer_size);
for (i = 0; i != buffer_size / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); ++i) {
if (buffer[i].Relationship == RelationCache && buffer[i].Cache.Level == 1) {
Size = buffer[i].Cache.Size;
break;
}
}
free(buffer);
return Size;
#else
//mingw can't do this, see bug http://sourceforge.net/p/mingw/bugs/1626/
// assume 32k
return 32768;
#endif
#else
#ifdef _MEZZ_THREAD_APPLE_
Whole CacheSize;
Whole CSSize = sizeof(CacheSize);
if(0==sysctlbyname("hw.l4icachesize", &CacheSize, &CSSize, NULL, 0))
{
return CacheSize;
}else{
if(0==sysctlbyname("hw.l3icachesize", &CacheSize, &CSSize, NULL, 0))
{
return CacheSize;
}else{
if(0==sysctlbyname("hw.l2icachesize", &CacheSize, &CSSize, NULL, 0))
{
return CacheSize;
}else{
if(0==sysctlbyname("hw.l1icachesize", &CacheSize, &CSSize, NULL, 0))
{
return CacheSize;
}else{
return 0;
}
}
}
}
#else
Whole CSSize = sysconf(_SC_LEVEL4_CACHE_SIZE);
if(!CSSize)
{
CSSize = sysconf(_SC_LEVEL3_CACHE_SIZE);
if(!CSSize)
{
CSSize = sysconf(_SC_LEVEL2_CACHE_SIZE);
if(!CSSize)
{ CSSize = sysconf(_SC_LEVEL1_DCACHE_SIZE); }
}
}
return CSSize;
#endif
#endif
}