wake-up-neo.com

Programmatisch die Cache-Zeilengröße ermitteln?

Alle Plattformen willkommen, bitte geben Sie die Plattform für Ihre Antwort an.

Eine ähnliche Frage: Wie wird die Seitengröße des CPU-Cache in C++ programmgesteuert ermittelt?

165
paxos1977

Unter Linux (mit einem einigermaßen aktuellen Kernel) können Sie diese Informationen aus/sys abrufen:

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

Dieses Verzeichnis hat ein Unterverzeichnis für jede Cache-Ebene. Jedes dieser Verzeichnisse enthält die folgenden Dateien:

coherency_line_size
level
number_of_sets
physical_line_partition
shared_cpu_list
shared_cpu_map
size
type
ways_of_associativity

Auf diese Weise erhalten Sie mehr Informationen über den Cache, als Sie jemals erhofft hätten, einschließlich der Cacheline-Größe (coherency_line_size) sowie welche CPUs diesen Cache gemeinsam nutzen. Dies ist sehr nützlich, wenn Sie Multithread-Programmierung mit gemeinsam genutzten Daten ausführen (bessere Ergebnisse werden erzielt, wenn die Threads, die Daten gemeinsam nutzen, auch einen Cache gemeinsam nutzen).

166
spinfire

Unter Linux schauen Sie sich sysconf (3) an.

sysconf (_SC_LEVEL1_DCACHE_LINESIZE)

Sie können es auch über die Befehlszeile mit getconf abrufen:

$ getconf LEVEL1_DCACHE_LINESIZE
64
128
ob1

Ich habe an ein paar Cache-Zeilen gearbeitet und musste eine plattformübergreifende Funktion schreiben. Ich habe es einem Github-Repo unter https://github.com/NickStrupat/CacheLineSize zugesagt, oder Sie können einfach die folgende Quelle verwenden. Fühlen Sie sich frei, damit zu tun, was Sie wollen.

#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
114
Nick Strupat

Unter x86 können Sie die Anweisung CPUID mit Funktion 2 verwenden, um verschiedene Eigenschaften des Caches und des TLB zu bestimmen. Das Parsen der Ausgabe von Funktion 2 ist etwas kompliziert, daher verweise ich auf Abschnitt 3.1.3 von Intel Processor Identification und CPUID Instruction (PDF).

Um diese Daten aus C/C++ - Code abzurufen, müssen Sie Inline-Assembly und Compiler-Eigenheiten verwenden oder eine externe Assembly-Funktion aufrufen, um die CPUID-Anweisung auszuführen.

31
Adam Rosenfield

Wenn Sie SDL2 verwenden, können Sie diese Funktion verwenden:

int SDL_GetCPUCacheLineSize(void);

Gibt die Größe der L1-Cachezeile in Byte zurück.

Führen Sie auf meinem x86_64-Computer den folgenden Codeausschnitt aus:

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

Erzeugt CacheLineSize = 64

Ich weiß, dass ich etwas spät dran bin, aber nur Informationen für zukünftige Besucher hinzufüge. In der SDL-Dokumentation wird derzeit angegeben, dass die zurückgegebene Nummer in KB angegeben ist, tatsächlich jedoch in Byte.

9
negamartin

Auf der Windows-Plattform:

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

Mit der Funktion GetLogicalProcessorInformation erhalten Sie Merkmale der vom System verwendeten logischen Prozessoren. Sie können die von der Funktion zurückgegebene SYSTEM_LOGICAL_PROCESSOR_INFORMATION durchsuchen, um nach Einträgen des Typs RelationCache zu suchen. Jeder dieser Einträge enthält eine ProcessorMask, die angibt, für welche Prozessoren der Eintrag gilt. Im CACHE_DESCRIPTOR wird angegeben, welcher Cache-Typ beschrieben wird und wie groß die Cache-Zeile für diesen Cache ist.

6

ARMv6 und höher hat C0 oder das Cache Type Register. Es ist jedoch nur im privilegierten Modus verfügbar.

Zum Beispiel aus Cortex ™ -A8 Technical Reference Manual :

Der Zweck des Cachetypregisters besteht darin, die minimale Zeilenlänge des Befehls und des Datencaches in Bytes zu bestimmen, um die Ungültigmachung eines Adressbereichs zu ermöglichen.

Das Cache-Typ-Register lautet:

  • ein Nur-Lese-Register
  • zugriff nur in privilegierten Modi.

Der Inhalt des Cachetypregisters hängt von der spezifischen Implementierung ab. Abbildung 3-2 zeigt die Bitanordnung des Cache Type Registers ...


Gehen Sie nicht davon aus, dass der ARM Prozessor einen Cache hat (anscheinend können einige ohne einen konfiguriert werden). Die Standardmethode für die Ermittlung ist C0. Aus dem ARM ARM , Seite B6-6:

In ARMv6 ist das System Control Coprozessor-Cache-Typ-Register die vorgeschriebene Methode zum Definieren der L1-Caches (siehe Cache-Typ-Register auf Seite B6-14). Es ist auch die empfohlene Methode für frühere Varianten der Architektur. Darüber hinaus werden unter Überlegungen zu zusätzlichen Cache-Ebenen auf Seite B6-12 Architekturrichtlinien für die Unterstützung von Cache-Ebenen 2 beschrieben.

4
jww

Sie können es auch programmgesteuert versuchen, indem Sie das Timing messen. Offensichtlich ist es nicht immer so präzise wie cpuid und dergleichen, aber es ist portabler. ATLAS erledigt dies in der Konfigurationsphase. Vielleicht möchten Sie es sich ansehen:

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

3