Obtain x86 cache info from CPU
The cache info today is hardcoded in cache.h
May not be optimal across various uarchs/SKUs
Leverage bionic sysconf to get the underlying cache.
Improvements seen on RPL, for various sizes
memmove_non_overlapping
1.25M - 31%
1.5M - 30%
1.75M - 28%
memcpy
1.25M - 31%
1.5M - 31%
1.75M - 30%
The bionic benchmarks (which only go up to 128KiB) show no change, as
you'd expect.
Test: bionic/tests/run-on-host.sh 64 && bionic/tests/run-on-host.sh 32
Bug: 202102347
Change-Id: I4bbad51794758873744149d0f58b86bb92ee307f
Signed-off-by: Vinay Prasad Kompella <vinay.kompella@intel.com>
Signed-off-by: Soni, Ravi Kumar <ravi.kumar.soni@intel.com>
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index 51f7ce9..8c1e7ec 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -62,6 +62,28 @@
__BIONIC_WEAK_VARIABLE_FOR_NATIVE_BRIDGE
const char* __progname;
+#if defined(__i386__) || defined(__x86_64__)
+// Default sizes based on the old hard-coded values for Atom/Silvermont (x86) and Core 2 (x86-64)...
+size_t __x86_data_cache_size = 24 * 1024;
+size_t __x86_data_cache_size_half = __x86_data_cache_size / 2;
+size_t __x86_shared_cache_size = sizeof(long) == 8 ? 4096 * 1024 : 1024 * 1024;
+size_t __x86_shared_cache_size_half = __x86_shared_cache_size / 2;
+// ...overwritten at runtime based on the cpu's reported cache sizes.
+static void __libc_init_x86_cache_info() {
+ // Handle the case where during early boot /sys fs may not yet be ready,
+ // resulting in sysconf() returning 0, leading to crashes.
+ // In that case (basically just init), we keep the defaults.
+ if (sysconf(_SC_LEVEL1_DCACHE_SIZE) != 0) {
+ __x86_data_cache_size = sysconf(_SC_LEVEL1_DCACHE_SIZE);
+ __x86_data_cache_size_half = __x86_data_cache_size / 2;
+ }
+ if (sysconf(_SC_LEVEL2_CACHE_SIZE) != 0) {
+ __x86_shared_cache_size = sysconf(_SC_LEVEL2_CACHE_SIZE);
+ __x86_shared_cache_size_half = __x86_shared_cache_size / 2;
+ }
+}
+#endif
+
void __libc_init_globals() {
// Initialize libc globals that are needed in both the linker and in libc.
// In dynamic binaries, this is run at least twice for different copies of the
@@ -171,6 +193,10 @@
__system_properties_init(); // Requires 'environ'.
__libc_init_fdsan(); // Requires system properties (for debug.fdsan).
__libc_init_fdtrack();
+
+#if defined(__i386__) || defined(__x86_64__)
+ __libc_init_x86_cache_info();
+#endif
}
void __libc_init_fork_handler() {