caching – Programmatically get the cache line size on Android-ThrowExceptions

Exception or error:

How do I get the cache line size on ARM Android? This is equivalent to the following page but specifically for Android:

Programmatically get the cache line size?

The answers on that page, and other ways I knew, do not work on Android:

  • /sys/devices/system/cpu/cpu0/cache/ does not exist.
  • _SC_LEVEL1_DCACHE_LINESIZE does not exist as a sysconf parameter, even if I manually pass in the value 190.
  • AT_DCACHEBSIZE does not exist as a getauxval parameter, even if I manually pass in the value 19.
  • /proc/cpuinfo does not contain cache line information.

Unlike x86, ARM’s CPU information is only available in kernel mode, so there’s no cpuid equivalent available to applications.

How to solve:

I carried out a small investigation and found something:

First of all, it seems like sysconf() with _SC_LEVEL1_ICACHE_SIZE, _SC_LEVEL1_ICACHE_ASSOC, _SC_LEVEL1_ICACHE_LINESIZE or other CPU cache-related flags always returns -1 (sometimes it could be 0) and it seems to be the reason for this, they’re simply not implemented.

But there’s a solution. Use this library if you’re able to use JNI in your project. This library is extremely helpful to retrieve information about the CPU (my device’s as old as hills):
enter image description here

Here’s the code I used to obtain information about my CPU caches:

#include <string>
#include <sstream>
#include <cpuinfo.h>

void get_cache_info(const char* name, const struct cpuinfo_cache* cache, std::ostringstream& oss)
{
    oss << "CPU Cache: " << name << std::endl;
    oss << " > size            : " << cache->size << std::endl;
    oss << " > associativity   : " << cache->associativity << std::endl;
    oss << " > sets            : " << cache->sets << std::endl;
    oss << " > partitions      : " << cache->partitions << std::endl;
    oss << " > line_size       : " << cache->line_size << std::endl;
    oss << " > flags           : " << cache->flags << std::endl;
    oss << " > processor_start : " << cache->processor_start << std::endl;
    oss << " > processor_count : " << cache->processor_count << std::endl;
    oss << std::endl;
}

const std::string get_cpu_info()
{
    cpuinfo_initialize();
    const struct cpuinfo_processor* proc = cpuinfo_get_current_processor();

    std::ostringstream oss;

    if (proc->cache.l1d)
        get_cache_info("L1 Data", proc->cache.l1d, oss);

    if (proc->cache.l1i)
        get_cache_info("L1 Instruction", proc->cache.l1i, oss);

    if (proc->cache.l2)
        get_cache_info("L2", proc->cache.l2, oss);

    if (proc->cache.l3)
        get_cache_info("L3", proc->cache.l3, oss);

    if (proc->cache.l4)
        get_cache_info("L4", proc->cache.l4, oss);

    return oss.str();
}

Leave a Reply

Your email address will not be published. Required fields are marked *