Программно получить размер строки кеша?

Все платформы приветствуются, пожалуйста, укажите платформу для вашего ответа.

Аналогичный вопрос: Как программно получить размер страницы кэша ЦП на С++?

Ответы

Ответ 1

В 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

Это дает вам больше информации о кеше, который вы когда-либо надеялись узнать, в том числе размер кешлайн, а также то, что CPU используют этот кеш. Это очень полезно, если вы выполняете многопоточное программирование с общими данными (вы получите лучшие результаты, если данные совместного использования потоков также будут совместно использовать кеш).

Ответ 2

В Linux посмотрите sysconf (3).

sysconf (_SC_LEVEL1_DCACHE_LINESIZE)

Вы также можете получить его из командной строки с помощью getconf:

$ getconf LEVEL1_DCACHE_LINESIZE
64

Ответ 3

Я работаю над некоторыми материалами в кеше и должен писать кросс-платформенную функцию. Я передал его репозиторию 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

В x86 вы можете использовать команду CPUID с функцией 2 для определения различных свойств кеша и TLB. Разбор вывода функции 2 несколько усложнен, поэтому я расскажу вам в разделе 3.1.3 Идентификация процессора Intel и инструкция CPUID ( PDF).

Чтобы получить эти данные из кода C/С++, вам нужно будет использовать встроенную сборку, встроенные функции компилятора или вызвать внешнюю сборку для выполнения команды CPUID.

Ответ 5

На платформе Windows:

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

GetLogicalProcessorInformation функция даст вам характеристики логических процессоров, используемых система. Вы можете пройти SYSTEM_LOGICAL_PROCESSOR_INFORMATION возвращается функцией, которая ищет записи типа RelationCache. каждый такая запись содержит ProcessorMask который сообщает вам, какой процессор запись применяется, и в CACHE_DESCRIPTOR, он сообщает вам, что тип кэша описывается и насколько велика линия кэша для этого Кэш.

Ответ 6

Если вы используете SDL2, вы можете использовать эту функцию:

int SDL_GetCPUCacheLineSize(void);

Возвращает размер строки строки кеша L1 в байтах.

На моем компьютере x86_64 выполняется этот фрагмент кода:

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

Производит CacheLineSize = 64

Я знаю, что немного опаздываю, но просто добавляю информацию для будущих посетителей. В документации SDL в настоящее время указано, что возвращаемый номер находится в КБ, но он фактически находится в байтах.

Ответ 7

ARMv6 и выше имеют C0 или регистр типа кэша. Однако он доступен только в привилегированном режиме.

Например, из Техническое справочное руководство Cortex ™ -A8:

Цель регистра типа кэша - определить инструкцию и минимальную длину строки кэша данных в байтах, чтобы включить диапазон адреса недействительны.

Регистр типа кэша:

  • регистр только для чтения
  • доступен только в привилегированных режимах.

Содержимое регистра типа кэша зависит от конкретного реализация. На рисунке 3-2 показано расположение бит кэша Тип Регистрация...


Не предполагайте, что процессор ARM имеет кэш (видимо, некоторые могут быть настроены без одного). Стандартный способ определить это через C0. Из ARM ARM, страница B6-6:

Из ARMv6 регистр типа кэша сопроцессора системы - это мандатный метод определения кеша L1, см. регистр типа кэша на стр. B6-14. Это также рекомендуемый метод для более ранних вариантов архитектура. Кроме того, соображения по дополнительным уровням кэш на стр. B6-12 описывает принципы архитектуры для уровня 2 поддержка кеша.

Ответ 8

Вы также можете попытаться сделать это программно, измерив некоторое время. Очевидно, что он не всегда будет таким точным, как cpuid и подобные, но он более портативен. ATLAS делает это на этапе конфигурации, вы можете посмотреть на него:

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