代码之家  ›  专栏  ›  技术社区  ›  Myria

在Android上以编程方式获取缓存线大小

  •  4
  • Myria  · 技术社区  · 8 年前

    如何在ARM Android上获取缓存线大小?这相当于以下页面,但专门针对Android:

    Programmatically get the cache line size?

    该页面上的答案以及我知道的其他方式在Android上不起作用:

    • /sys/devices/system/cpu/cpu0/cache/ 不存在。
    • _SC_LEVEL1_DCACHE_LINESIZE 不作为存在 sysconf 参数,即使我手动传入值 190 。
    • AT_DCACHEBSIZE 不作为存在 getauxval 参数,即使我手动传入值 19 。
    • /proc/cpuinfo 不包含缓存线信息。

    与x86不同,ARM的CPU信息仅在内核模式下可用,因此没有 cpuid 应用程序可用的等效项。

    1 回复  |  直到 8 年前
        1
  •  4
  •   Netherwire    6 年前

    我进行了一次小调查,发现了一些东西:

    首先,看起来 sysconf() 具有 _SC_LEVEL1_ICACHE_SIZE ,则, _SC_LEVEL1_ICACHE_ASSOC ,则, _SC_LEVEL1_ICACHE_LINESIZE 或其他与CPU缓存相关的标志始终返回-1(有时可能是0)和 it seems to be the reason for this ,它们根本没有实现。

    但有一个解决方案。使用 this library 如果您能够在项目中使用JNI。此库对于检索有关CPU的信息非常有用(我的设备非常古老): enter image description here

    下面是我用来获取CPU缓存信息的代码:

    #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();
    }