c++ - 在 osx 中使用 C/C++ 和内联汇编/内在函数获取缓存信息

标签 c++ c caching cpu inline-assembly

我使用 gcc __get_cpuid 和内联汇编编写了以下程序来获取笔记本电脑的缓存信息,但无法在我在网上找到的关于(缓存和 TLB 描述符的编码)的表中识别它们.

#include <stdio.h>
#include <stdlib.h> 
#include <assert.h>
#include <string.h>
#include <time.h>
#include <stdint.h>
#include <math.h>
#include <cpuid.h>

static inline void cpuid(uint32_t *eax, uint32_t *ebx,
                         uint32_t *ecx, uint32_t *edx);

int main() {
    uint32_t a, b, c, d;
    uint32_t eax, ebx, ecx, edx;
    eax = 2; /* processor info and feature bits */
    uint32_t command = 2;
    cpuid(&eax, &ebx, &ecx, &edx);
    __get_cpuid(command, &a, &b, &c, &d);

    printf("eax: %08x\n", eax);
    printf("ebx: %08x\n", ebx);
    printf("ecx: %08x\n", ecx);
    printf("edx: %08x\n", edx);

    printf("a: %08x\n", a);
    printf("b: %08x\n", b);
    printf("c: %08x\n", c);
    printf("d: %08x\n", d);
}

static inline void cpuid(uint32_t *eax, uint32_t *ebx,
                         uint32_t *ecx, uint32_t *edx)
{
        /* ecx is often an input as well as an output. */
        asm ("cpuid"
            : "=a" (*eax),
              "=b" (*ebx),
              "=c" (*ecx),
              "=d" (*edx)
            : "0" (*eax));
}

我的输出:

eax: 76036301
ebx: 00f0b5ff
ecx: 00000000
edx: 00c10000
a: 76036301
b: 00f0b5ff
c: 00000000
d: 00c10000

我从 here 找到这张表 enter image description here

我使用 sysctl hw.cachesize 并找到了

L1 cache: 32KB
L2 cache: 256KB
L3 cache: 6MB

我的环境:

system: os x 10.10.1
compiler: clang-602.0.53
CPU: I7-4850 HQ 2.3HZ

我的程序有什么问题?我的程序应该可以工作,因为这两种方法都给出相同的结果......我对此感到困惑。谢谢!

编辑: 我尝试了 Mats 的建议,并得到以下输出:

gcc intrinsic
a: 76036301
b: 00f0b5ff
c: 00000000
d: 00c10000
eax: 2
eax: 76036301
ebx: 00f0b5ff
ecx: 00000000
edx: 00c10000
eax: 4, ecx: 0
eax: 1c004121
ebx: 01c0003f
ecx: 0000003f
edx: 00000000
eax: 4, ecx: 1
eax: 1c004122
ebx: 01c0003f
ecx: 0000003f
edx: 00000000
eax: 4, ecx: 2
eax: 1c004143
ebx: 01c0003f
ecx: 000001ff
edx: 00000000
eax: 4, ecx: 3
eax: 1c03c163
ebx: 02c0003f
ecx: 00001fff
edx: 00000006
eax: 4, ecx: 4
eax: 1c03c183
ebx: 03c0f03f
ecx: 00001fff
edx: 00000004
eax: 4, ecx: 5
eax: 00000000
ebx: 00000000
ecx: 00000000
edx: 00000000

我在 here 查找表格
静态 cpuid_cache_descriptor_t intel_cpuid_leaf2_descriptor_table[] = {

//  -------------------------------------------------------
//  value   type    level       ways    size    entries
//  -------------------------------------------------------
    { 0x00, _NULL_, NA,     NA, NA, NA  },
    { 0x01, TLB,    INST,       4,  SMALL,  32  },  
    { 0x02, TLB,    INST,       FULLY,  LARGE,  2   },  
    { 0x03, TLB,    DATA,       4,  SMALL,  64  },  
    { 0x04, TLB,    DATA,       4,  LARGE,  8   },  
    { 0x05, TLB,    DATA1,      4,  LARGE,  32  },  
    { 0x06, CACHE,  L1_INST,    4,  8*K,    32  },
    { 0x08, CACHE,  L1_INST,    4,  16*K,   32  },
    { 0x09, CACHE,  L1_INST,    4,  32*K,   64  },
    { 0x0A, CACHE,  L1_DATA,    2,  8*K,    32  },
    { 0x0B, TLB,    INST,       4,  LARGE,  4   },  
    { 0x0C, CACHE,  L1_DATA,    4,  16*K,   32  },
    { 0x0D, CACHE,  L1_DATA,    4,  16*K,   64  },
    { 0x0E, CACHE,  L1_DATA,    6,  24*K,   64  },
    { 0x21, CACHE,  L2,     8,  256*K,  64  },
    { 0x22, CACHE,  L3_2LINESECTOR, 4,  512*K,  64  },
    { 0x23, CACHE,  L3_2LINESECTOR, 8,  1*M,    64  },
    { 0x25, CACHE,  L3_2LINESECTOR, 8,  2*M,    64  },
    { 0x29, CACHE,  L3_2LINESECTOR, 8,  4*M,    64  },
    { 0x2C, CACHE,  L1_DATA,    8,  32*K,   64  },
    { 0x30, CACHE,  L1_INST,    8,  32*K,   64  },
    { 0x40, CACHE,  L2,     NA, 0,  NA  },
    { 0x41, CACHE,  L2,     4,  128*K,  32  },
    { 0x42, CACHE,  L2,     4,  256*K,  32  },
    { 0x43, CACHE,  L2,     4,  512*K,  32  },
    { 0x44, CACHE,  L2,     4,  1*M,    32  },
    { 0x45, CACHE,  L2,     4,  2*M,    32  },
    { 0x46, CACHE,  L3,     4,  4*M,    64  },
    { 0x47, CACHE,  L3,     8,  8*M,    64  },
    { 0x48, CACHE,  L2,     12,     3*M,    64  },
    { 0x49, CACHE,  L2,     16, 4*M,    64  },
    { 0x4A, CACHE,  L3,     12,     6*M,    64  },
    { 0x4B, CACHE,  L3,     16, 8*M,    64  },
    { 0x4C, CACHE,  L3,     12,     12*M,   64  },
    { 0x4D, CACHE,  L3,     16, 16*M,   64  },
    { 0x4E, CACHE,  L2,     24, 6*M,    64  },
    { 0x4F, TLB,    INST,       NA, SMALL,  32  },  
    { 0x50, TLB,    INST,       NA, BOTH,   64  },  
    { 0x51, TLB,    INST,       NA, BOTH,   128 },  
    { 0x52, TLB,    INST,       NA, BOTH,   256 },  
    { 0x55, TLB,    INST,       FULLY,  BOTH,   7   },  
    { 0x56, TLB,    DATA0,      4,  LARGE,  16  },  
    { 0x57, TLB,    DATA0,      4,  SMALL,  16  },  
    { 0x59, TLB,    DATA0,      FULLY,  SMALL,  16  },  
    { 0x5A, TLB,    DATA0,      4,  LARGE,  32  },  
    { 0x5B, TLB,    DATA,       NA, BOTH,   64  },  
    { 0x5C, TLB,    DATA,       NA, BOTH,   128 },  
    { 0x5D, TLB,    DATA,       NA, BOTH,   256 },  
    { 0x60, CACHE,  L1,     16*K,   8,  64  },
    { 0x61, CACHE,  L1,     4,  8*K,    64  },
    { 0x62, CACHE,  L1,     4,  16*K,   64  },
    { 0x63, CACHE,  L1,     4,  32*K,   64  },
    { 0x70, CACHE,  TRACE,      8,  12*K,   NA  },
    { 0x71, CACHE,  TRACE,      8,  16*K,   NA  },
    { 0x72, CACHE,  TRACE,      8,  32*K,   NA  },
    { 0x78, CACHE,  L2,     4,  1*M,    64  },
    { 0x79, CACHE,  L2_2LINESECTOR, 8,  128*K,  64  },
    { 0x7A, CACHE,  L2_2LINESECTOR, 8,  256*K,  64  },
    { 0x7B, CACHE,  L2_2LINESECTOR, 8,  512*K,  64  },
    { 0x7C, CACHE,  L2_2LINESECTOR, 8,  1*M,    64  },
    { 0x7D, CACHE,  L2,     8,  2*M,    64  },
    { 0x7F, CACHE,  L2,     2,  512*K,  64  },
    { 0x80, CACHE,  L2,     8,  512*K,  64  },
    { 0x82, CACHE,  L2,     8,  256*K,  32  },
    { 0x83, CACHE,  L2,     8,  512*K,  32  },
    { 0x84, CACHE,  L2,     8,  1*M,    32  },
    { 0x85, CACHE,  L2,     8,  2*M,    32  },
    { 0x86, CACHE,  L2,     4,  512*K,  64  },
    { 0x87, CACHE,  L2,     8,  1*M,    64  },
    { 0xB0, TLB,    INST,       4,  SMALL,  128 },  
    { 0xB1, TLB,    INST,       4,  LARGE,  8   },  
    { 0xB2, TLB,    INST,       4,  SMALL,  64  },  
    { 0xB3, TLB,    DATA,       4,  SMALL,  128 },  
    { 0xB4, TLB,    DATA1,      4,  SMALL,  256 },  
    { 0xBA, TLB,    DATA1,      4,  BOTH,   64  },  
    { 0xCA, STLB,   DATA1,      4,  BOTH,   512 },  
    { 0xD0, CACHE,  L3,     4,  512*K,  64  },  
    { 0xD1, CACHE,  L3,     4,  1*M,    64  },  
    { 0xD2, CACHE,  L3,     4,  2*M,    64  },  
    { 0xD3, CACHE,  L3,     4,  4*M,    64  },  
    { 0xD4, CACHE,  L3,     4,  8*M,    64  },  
    { 0xD6, CACHE,  L3,     8,  1*M,    64  },  
    { 0xD7, CACHE,  L3,     8,  2*M,    64  },  
    { 0xD8, CACHE,  L3,     8,  4*M,    64  },  
    { 0xD9, CACHE,  L3,     8,  8*M,    64  },  
    { 0xDA, CACHE,  L3,     8,  12*M,   64  },  
    { 0xDC, CACHE,  L3,     12,     1536*K, 64  },  
    { 0xDD, CACHE,  L3,     12,     3*M,    64  },  
    { 0xDE, CACHE,  L3,     12,     6*M,    64  },  
    { 0xDF, CACHE,  L3,     12, 12*M,   64  },  
    { 0xE0, CACHE,  L3,     12, 18*M,   64  },  
    { 0xE2, CACHE,  L3,     16, 2*M,    64  },  
    { 0xE3, CACHE,  L3,     16, 4*M,    64  },  
    { 0xE4, CACHE,  L3,     16, 8*M,    64  },  
    { 0xE5, CACHE,  L3,     16, 16*M,   64  },  
    { 0xE6, CACHE,  L3,     16, 24*M,   64  },  
    { 0xF0, PREFETCH, NA,       NA, 64, NA  },  
    { 0xF1, PREFETCH, NA,       NA, 128,    NA  }   
};

现在的问题是我仍然无法获得我的 L3 缓存的正确大小(当 ecx=1 时,我得到 22 即 512K,但正确的值是 6MB)。另外,我的 L2 缓存的大小似乎存在一些冲突(43(当 ecx=2 时)和 21(当 ecx=0 时))

最佳答案

因此,您的数据似乎相当正确,只是您使用的是旧引用。不幸的是,英特尔的网站要么目前已损坏,要么不喜欢 Firefox 和/或 Linux。

76036301

76 表示具有 64K 操作的跟踪缓存。

03 表示具有 64 个条目的 4 路 DATA TLB。

63 是 32KB 一级缓存 - 来源 here显示该值,这不在您的文档中。

01 表示具有 32 个条目的 4 路指令 TLB。

00f0b5ff 给

00“无”

f0 预取,64 个条目。

0b 指令 4 路 TLB,用于大页面,4 个条目。

b5 甚至在那个链接上也没有记录。 【猜猜小数据TLB】

要获得 L2 和 L3 缓存大小,您需要使用 EAX=4 的 CPUID,并将每个缓存级别的 ECX 设置为 0、1、2 ...。链接的代码显示了这一点,英特尔的文档详细说明了哪些位的含义。

关于c++ - 在 osx 中使用 C/C++ 和内联汇编/内在函数获取缓存信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35395811/

相关文章:

php - PNG 图像输出的标题以确保它在浏览器中缓存?

c# - .NET 应用程序缓存与数据库缓存

c++ - 接受 lambda 作为函数参数并提取返回类型

c++ - 为什么重载运算符不将主要对象设置为值集

c++ - 返回类型 int 的函数默认返回值 1?

c - 检测并防止 C 中 unsigned long 溢出

c++ - C 和 C++ 中的图形

java - Spring 和 JUnit |如何禁用特定测试类的 spring 测试上下文缓存?

c++ - 为什么运算符不能放在括号中?

c - Nordic SDK 打印到串口