代码之家  ›  专栏  ›  技术社区  ›  Thierry Roy

以编程方式获取缓存线大小?

  •  157
  • Thierry Roy  · 技术社区  · 5 年前

    欢迎所有平台,请为您的答案指定平台。

    类似的问题: How to programmatically get the CPU cache page size in C++?

    8 回复  |  直到 6 年前
        1
  •  161
  •   Chai T. Rex    6 年前

    在Linux上(有一个相当新的内核),您可以从/sys中获取这些信息:

    /sys/devices/system/cpu/cpu0/cache/
    

    此目录对于每个缓存级别都有一个子目录。每个目录都包含以下文件:

    coherency_line_size
    level
    number_of_sets
    physical_line_partition
    shared_cpu_list
    shared_cpu_map
    size
    type
    ways_of_associativity
    

    这将提供有关缓存的更多信息,包括缓存线大小( coherency_line_size )以及哪些CPU共享这个缓存。如果使用共享数据进行多线程编程,这非常有用(如果共享数据的线程也共享缓存,则会获得更好的结果)。

        2
  •  122
  •   Bryan Denny    14 年前

    在Linux上,查看sysconf(3)。

    sysconf (_SC_LEVEL1_DCACHE_LINESIZE)
    

    您还可以使用getconf从命令行获取:

    $ getconf LEVEL1_DCACHE_LINESIZE
    64
    
        3
  •  111
  •   Nick Strupat    10 年前

    我一直在做一些缓存线的工作,需要编写一个跨平台的函数。我把它交给了github的回购协议 https://github.com/NickStrupat/CacheLineSize ,或者您可以使用下面的源代码。你想怎么做就怎么做。

    #ifndef GET_CACHE_LINE_SIZE_H_INCLUDED
    #define GET_CACHE_LINE_SIZE_H_INCLUDED
    
    // Author: Nick Strupat
    // Date: October 29, 2010
    // Returns the cache line size (in bytes) of the processor, or 0 on failure
    
    #include <stddef.h>
    size_t cache_line_size();
    
    #if defined(__APPLE__)
    
    #include <sys/sysctl.h>
    size_t cache_line_size() {
        size_t line_size = 0;
        size_t sizeof_line_size = sizeof(line_size);
        sysctlbyname("hw.cachelinesize", &line_size, &sizeof_line_size, 0, 0);
        return line_size;
    }
    
    #elif defined(_WIN32)
    
    #include <stdlib.h>
    #include <windows.h>
    size_t cache_line_size() {
        size_t line_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) {
                line_size = buffer[i].Cache.LineSize;
                break;
            }
        }
    
        free(buffer);
        return line_size;
    }
    
    #elif defined(linux)
    
    #include <stdio.h>
    size_t cache_line_size() {
        FILE * p = 0;
        p = fopen("/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size", "r");
        unsigned int i = 0;
        if (p) {
            fscanf(p, "%d", &i);
            fclose(p);
        }
        return i;
    }
    
    #else
    #error Unrecognized platform
    #endif
    
    #endif
    
        4
  •  30
  •   Adam Rosenfield    15 年前

    在x86上,可以使用 CPUID 带函数2的指令,用于确定缓存和TLB的各种属性。解析函数2的输出有些复杂,所以我将介绍 Intel Processor Identification and the CPUID Instruction (PDF)。

    要从C/C++代码中获取这些数据,您需要使用内联汇编、编译器内联函数或调用外部程序集函数来执行CPUID指令。

        5
  •  8
  •   negamartin    8 年前

    如果使用的是SDL2,则可以使用此函数:

    int SDL_GetCPUCacheLineSize(void);
    

    它返回一级缓存线大小的字节数。

    在x86_64计算机中,运行以下代码段:

    printf("CacheLineSize = %d",SDL_GetCPUCacheLineSize());
    

    生产 CacheLineSize = 64

    我知道我有点晚了,但只是给未来的访客添加信息。 SDL文档目前说返回的数字是以KB为单位的,但实际上是以字节为单位的。

        6
  •  6
  •   Johan Boulé    7 年前

    在Windows平台上:

    http://blogs.msdn.com/oldnewthing/archive/2009/12/08/9933836.aspx

    GetLogicalProcessorInformation 函数将为您提供特征 使用的逻辑处理器 制度。你可以走 系统逻辑处理器信息 由正在查找的函数返回 RelationCache类型的条目。各 这样的条目包含一个processormask 它告诉你哪个处理器 条目适用于 缓存描述符,它告诉你 正在描述缓存类型,并且 缓存线有多大 隐藏物。

        7
  •  4
  •   jww    9 年前

    ARMV6及以上 C0 或缓存类型寄存器。但是,它只在特权模式下可用。

    例如,来自 Cortex™-A8 Technical Reference Manual :

    缓存类型寄存器的目的是确定指令 和数据缓存的最小行长度(字节),以启用 无效地址。

    缓存类型寄存器是:

    • 只读寄存器
    • 只能在特权模式下访问。

    缓存类型寄存器的内容取决于 实施。图3-2显示了缓存的位排列 键入寄存器…


    不要假设arm处理器有一个缓存(显然,有些可以在没有缓存的情况下配置)。确定它的标准方法是通过 C0 . 从 ARM ARM ,B6—6页:

    在ARMV6中,系统控制协处理器缓存类型寄存器是 用于定义一级缓存的强制方法,请参阅上的缓存类型寄存器 B6—14页。对于早期的 建筑。此外,考虑到 第B6-12页上的缓存描述了第2级的体系结构指南 缓存支持。

        8
  •  2
  •   David Cournapeau    15 年前

    您也可以通过测量一些时间来尝试以编程的方式完成。显然,它并不总是像cpuid等那样精确,但它更便于移植。阿特拉斯在它的配置阶段,你可能想看看它:

    http://math-atlas.sourceforge.net/