2009-04-27 13 views

Respuesta

29

en x86, puede utilizar la instrucción CPUID con la función 2 para determinar varias propiedades de la memoria caché y el TLB. Analizar el resultado de la función 2 es algo complicado, así que lo referiré a la sección 3.1.3 del Intel Processor Identification and the CPUID Instruction (PDF).

Para obtener estos datos del código C/C++, deberá usar el ensamblaje en línea, los intrínsecos del compilador o llamar a una función de ensamblaje externo para realizar la instrucción CPUID.

+0

conoce a alguien ¿Cómo hacer esto con otros procesadores con caché integrada? – paxos1977

+2

@ceretullis: Errr ... el x86 tiene memoria incorporada. ¿Qué "otros procesadores" buscas específicamente?Lo que estás pidiendo depende de la plataforma. –

2

También puede intentar hacerlo programáticamente midiendo algunos tiempos. Obviamente, no siempre será tan preciso como cpuid y los gustos, pero es más portátil. ATLAS lo hace en su fase de configuración, es posible que desee mirarlo:

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

143

En Linux (con un núcleo bastante reciente), se puede obtener esta información de/sys:

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

Este directorio tiene un subdirectorio para cada nivel de caché. Cada uno de estos directorios contiene los siguientes archivos:

coherency_line_size 
level 
number_of_sets 
physical_line_partition 
shared_cpu_list 
shared_cpu_map 
size 
type 
ways_of_associativity 

Esto le da más información acerca de la caché, entonces jamás esperaría saber, incluyendo el tamaño cacheline, así como qué parte CPUs esta caché. Esto es muy útil si está realizando una programación multiproceso con datos compartidos (obtendrá mejores resultados si los subprocesos que comparten datos también comparten una caché).

+4

¿cuál de los archivos contiene el tamaño de la línea de caché? Estoy asumiendo el coherency_line_size? o la physical_line_partition? – paxos1977

+19

coherency_line_size – spinfire

+5

Para estar seguro: esto está en Bytes, ¿sí? –

6

En la plataforma Windows:

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

La función GetLogicalProcessorInformation le dará características de los procesadores lógicos en uso por el sistema . Puede recorrer el SYSTEM_LOGICAL_PROCESSOR_INFORMATION devuelto por la función que busca entradas de tipo RelationCache. Cada dicha entrada contiene un ProcessorMask que le dice qué procesador (s) de la entrada se aplica a, y en el CACHE_DESCRIPTOR, te dice lo que está siendo descrito tipo de memoria caché y cuán grande es la línea de caché es para que cache.

104

En Linux, mire sysconf (3).

sysconf (_SC_LEVEL1_DCACHE_LINESIZE) 

También puede obtener desde la línea de comandos usando getconf:

$ getconf LEVEL1_DCACHE_LINESIZE 
64 
+3

¡las respuestas simples son simplemente las mejores! –

+0

¿cuál es la unidad? bits o bytes? – warunapww

+1

@warunapww Está en bytes. –

100

He estado trabajando en algunas cosas línea de caché y tenía que escribir una función multi-plataforma. Lo envié a un repositorio de Github al https://github.com/NickStrupat/CacheLineSize, o puedes usar la fuente a continuación. Siéntete libre de hacer lo que quieras con él.

#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 
+11

Sería mejor utilizar sysconf (_SC_LEVEL1_DCACHE_LINESIZE) para Linux. – Matt

4

ARMv6 y por encima tiene C0 o el tipo de registro de caché. Sin embargo, solo está disponible en modo privilegiado.

Por ejemplo, desde Cortex™-A8 Technical Reference Manual:

El propósito del Registro Tipo de caché es determinar la longitud de la instrucción y la línea de caché mínimo de datos en bytes para permitir un rango de direcciones a invalidar.

El caché tipo de registro es:

  • un registro de sólo lectura
  • accesible sólo en los modos privilegiados.

El contenido del Registro de tipo de caché depende de la implementación específica de . La figura 3-2 muestra la disposición de bits de la caché Tipo Registro ...


no tengan el procesador ARM tiene un caché (al parecer, algunos pueden ser configurados sin uno). La forma estándar de determinarlo es a través de C0. Desde el ARM ARM, página B6-6:

De ARMv6, el registro de Tipo de control Sistema Coprocesador caché es el método mandato para definir las cachés L1, ver Caché tipo de registro en la página B6-14. También es el método recomendado para las versiones anteriores de de la arquitectura. Además, Consideraciones para niveles adicionales de caché en la página B6-12 describe las pautas de arquitectura para el nivel 2 de soporte de caché.

5

Si está utilizando SDL2 puede utilizar esta función:

int SDL_GetCPUCacheLineSize(void); 

que devuelve el tamaño del tamaño de línea de caché L1, en bytes.

En mi máquina x86_64, la ejecución de este fragmento de código:

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

Produce CacheLineSize = 64

Yo sé que soy un poco tarde, pero sólo la adición de información para futuros visitantes. La documentación de SDL actualmente dice que el número devuelto está en KB, pero en realidad está en bytes.

+0

Oh, esto es realmente útil. Voy a escribir algún juego en SDL2, así que esto va a ser realmente útil –

Cuestiones relacionadas