summaryrefslogtreecommitdiff
path: root/src/pal/src/misc/sysinfo.cpp
diff options
context:
space:
mode:
authorSteve MacLean <sdmaclea.qdt@qualcommdatacenter.com>2017-08-02 06:48:14 -0400
committerJan Vorlicek <janvorli@microsoft.com>2017-08-02 12:48:14 +0200
commitbdf219c364e15cae908f9c87446ff4ae26a9fe1e (patch)
tree8bb8b6687dcf4cfb9fd7c4a105db3d1c9b97a820 /src/pal/src/misc/sysinfo.cpp
parent11c911e6f49fdc95fc52bec8d930df7e5c50daa9 (diff)
downloadcoreclr-bdf219c364e15cae908f9c87446ff4ae26a9fe1e.tar.gz
coreclr-bdf219c364e15cae908f9c87446ff4ae26a9fe1e.tar.bz2
coreclr-bdf219c364e15cae908f9c87446ff4ae26a9fe1e.zip
[Arm64] GetLargestOnDieCacheSize (#13071)
Look for cache info in /sys/.../cache/index*/size If that fails estimate cache size based on processor count
Diffstat (limited to 'src/pal/src/misc/sysinfo.cpp')
-rw-r--r--src/pal/src/misc/sysinfo.cpp89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/pal/src/misc/sysinfo.cpp b/src/pal/src/misc/sysinfo.cpp
index e1785688dc..a06f4b75cb 100644
--- a/src/pal/src/misc/sysinfo.cpp
+++ b/src/pal/src/misc/sysinfo.cpp
@@ -384,6 +384,52 @@ PAL_HasGetCurrentProcessorNumber()
return HAVE_SCHED_GETCPU;
}
+bool
+ReadMemoryValueFromFile(const char* filename, size_t* val)
+{
+ bool result = false;
+ char *line = nullptr;
+ size_t lineLen = 0;
+ char* endptr = nullptr;
+ size_t num = 0, l, multiplier;
+
+ if (val == nullptr)
+ return false;
+
+ FILE* file = fopen(filename, "r");
+ if (file == nullptr)
+ goto done;
+
+ if (getline(&line, &lineLen, file) == -1)
+ goto done;
+
+ errno = 0;
+ num = strtoull(line, &endptr, 0);
+ if (errno != 0)
+ goto done;
+
+ multiplier = 1;
+ switch(*endptr)
+ {
+ case 'g':
+ case 'G': multiplier = 1024;
+ case 'm':
+ case 'M': multiplier = multiplier*1024;
+ case 'k':
+ case 'K': multiplier = multiplier*1024;
+ }
+
+ *val = num * multiplier;
+ result = true;
+ if (*val/multiplier != num)
+ result = false;
+done:
+ if (file)
+ fclose(file);
+ free(line);
+ return result;
+}
+
size_t
PALAPI
PAL_GetLogicalProcessorCacheSizeFromOS()
@@ -403,5 +449,48 @@ PAL_GetLogicalProcessorCacheSizeFromOS()
cacheSize = max(cacheSize, sysconf(_SC_LEVEL4_CACHE_SIZE));
#endif
+#if defined(_ARM64_)
+ if(cacheSize == 0)
+ {
+ size_t size;
+
+ if(ReadMemoryValueFromFile("/sys/devices/system/cpu/cpu0/cache/index0/size", &size))
+ cacheSize = max(cacheSize, size);
+ if(ReadMemoryValueFromFile("/sys/devices/system/cpu/cpu0/cache/index1/size", &size))
+ cacheSize = max(cacheSize, size);
+ if(ReadMemoryValueFromFile("/sys/devices/system/cpu/cpu0/cache/index2/size", &size))
+ cacheSize = max(cacheSize, size);
+ if(ReadMemoryValueFromFile("/sys/devices/system/cpu/cpu0/cache/index3/size", &size))
+ cacheSize = max(cacheSize, size);
+ if(ReadMemoryValueFromFile("/sys/devices/system/cpu/cpu0/cache/index4/size", &size))
+ cacheSize = max(cacheSize, size);
+ }
+
+ if(cacheSize == 0)
+ {
+ // It is currently expected to be missing cache size info
+ //
+ // _SC_LEVEL*_*CACHE_SIZE is not yet present. Work is in progress to enable this for arm64
+ //
+ // /sys/devices/system/cpu/cpu*/cache/index*/ is also not yet present in most systems.
+ // Arm64 patch is in Linux kernel tip.
+ //
+ // midr_el1 is available in "/sys/devices/system/cpu/cpu0/regs/identification/midr_el1",
+ // but without an exhaustive list of ARM64 processors any decode of midr_el1
+ // Would likely be incomplete
+
+ // Published information on ARM64 architectures is limited.
+ // If we use recent high core count chips as a guide for state of the art, we find
+ // total L3 cache to be 1-2MB/core. As always, there are exceptions.
+
+ // Estimate cache size based on CPU count
+ // Assume lower core count are lighter weight parts which are likely to have smaller caches
+ // Assume L3$/CPU grows linearly from 256K to 1.5M/CPU as logicalCPUs grows from 2 to 12 CPUs
+ DWORD logicalCPUs = PAL_GetLogicalCpuCountFromOS();
+
+ cacheSize = logicalCPUs*min(1536, max(256, logicalCPUs*128))*1024;
+ }
+#endif
+
return cacheSize;
}