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

147

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

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

  • 8
    FWIW, C ++ 17 обеспечит приближение времени компиляции этого: stackoverflow.com/questions/39680206/…
  • 0
    Кроме C / C ++, если вы не возражаете против использования ассемблера для получения такой информации, вы можете взглянуть (расширив информацию из ответа Негамартина) на исходный код SDL_GetCPUCacheLineSize функции SDL_GetCPUCacheLineSize , а затем взгляните на cpuid macro имеющий исходный код сборки. код для каждой модели процессора. Вы можете взглянуть на imgur.com/a/KP57m6s или непосредственно взглянуть на источник самостоятельно.
Теги:
caching
operating-system
systems-programming

8 ответов

133

В 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 используют этот кеш. Это очень полезно, если вы выполняете многопоточное программирование с общими данными (вы получите лучшие результаты, если данные совместного использования потоков также будут совместно использовать кеш).

  • 4
    какой из файлов содержит размер строки кэша? Я предполагаю, что coherency_line_size? или физическая_линя_раздела?
  • 22
    coherency_line_size
Показать ещё 6 комментариев
101

Я работаю над некоторыми материалами в кеше и должен писать кросс-платформенную функцию. Я передал его репозиторию 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
  • 13
    Возможно, лучше использовать sysconf (_SC_LEVEL1_DCACHE_LINESIZE) для Linux.
  • 0
    @ Матт почему? Просто любопытно :-).
101

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

sysconf (_SC_LEVEL1_DCACHE_LINESIZE)

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

$ getconf LEVEL1_DCACHE_LINESIZE
64
  • 4
    простые ответы - просто лучшие!
  • 0
    что такое блок? биты или байты?
Показать ещё 2 комментария
28

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

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

  • 0
    Кто-нибудь знает о том, как это сделать с другими процессорами со встроенным кешем?
  • 2
    @ceretullis: Errr ... x86 имеет встроенный кеш. Какие "другие процессоры" вы специально ищете? То, что вы просите, зависит от платформы.
6

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

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

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

5

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

int SDL_GetCPUCacheLineSize(void);

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

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

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

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

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

  • 0
    О, это действительно полезно. Я собираюсь написать какую-нибудь игру на SDL2, так что это будет очень полезно
4

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

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

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

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

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

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


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

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

2

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню