Есть ли способ проверить, был ли недавно очищен кэш процессора? - PullRequest
10 голосов
/ 18 мая 2011

на i386 linux. Предпочтительно в c / (c / posix std libs) / proc, если это возможно. Если нет, то есть ли какая-нибудь сборка или сторонняя библиотека, которая может это сделать?

Редактировать: я пытаюсь разработать тест, очищает ли модуль ядра строку кэша или весь процессор (с помощью wbinvd ()). Программа запускается от имени пользователя root, но я бы предпочел остаться в пространстве пользователя, если это возможно.

Ответы [ 3 ]

12 голосов
/ 05 июля 2011

Кэш-связные системы делают все возможное, чтобы скрыть такие вещи от вас.Я думаю, что вам придется наблюдать это косвенно, либо используя регистры подсчета производительности для обнаружения ошибок в кеше, либо тщательно измеряя время для чтения области памяти с таймером высокого разрешения.

Эта программа работает на моем компьютере x86_64продемонстрировать эффекты clflush.Время, необходимое для чтения глобальной переменной, используя rdtsc.Будучи единственной инструкцией, привязанной непосредственно к тактовой частоте процессора, для этого идеально подходит rdtsc.

Вот вывод:

took 81 ticks
took 81 ticks
flush: took 387 ticks
took 72 ticks

Вы видите 3 испытания: Первое гарантирует i находится в кеше (это так, потому что он был только обнулен как часть BSS), второе - чтение i, которое должно быть в кеше.Затем clflush выбрасывает i из кэша (вместе со своими соседями) и показывает, что повторное чтение занимает значительно больше времени.Окончательное чтение подтверждает, что оно снова в кеше.Результаты очень воспроизводимы, и разница достаточно существенна, чтобы легко увидеть ошибки в кеше.Если вы захотите откалибровать служебные данные rdtsc(), вы можете сделать разницу еще более заметной.

Если вы не можете прочитать адрес памяти, который хотите проверить (хотя даже mmap из /dev/mem следуетработать для этих целей) вы можете сделать вывод, что вы хотите, если вы знаете размер строки кэширования и ассоциативность кэша.Затем вы можете использовать доступные области памяти для проверки активности в интересующем вас наборе.

Исходный код:

#include <stdio.h>
#include <stdint.h>

inline void
clflush(volatile void *p)
{
    asm volatile ("clflush (%0)" :: "r"(p));
}

inline uint64_t
rdtsc()
{
    unsigned long a, d;
    asm volatile ("rdtsc" : "=a" (a), "=d" (d));
    return a | ((uint64_t)d << 32);
}

volatile int i;

inline void
test()
{
    uint64_t start, end;
    volatile int j;

    start = rdtsc();
    j = i;
    end = rdtsc();
    printf("took %lu ticks\n", end - start);
}

int
main(int ac, char **av)
{
    test();
    test();
    printf("flush: ");
    clflush(&i);
    test();
    test();
    return 0;
}
3 голосов
/ 02 июля 2011

Я не знаю ни одной универсальной команды для получения состояния кэша, но есть способы:

  1. Полагаю, это самое простое: если у вас есть модуль ядра, просто разберите его и поищите команды аннулирования / очистки кэша (мне пришло только 3: WBINDVD, CLFLUSH, INVD).
  2. Вы только что сказали, что это для i386, но я думаю, вы не имеете в виду 80386. Проблема в том, что есть много разных с различными расширениями и функциями. Например. В новейшей серии Intel есть несколько регистров производительности / профилирования для системы кеша, которые вы можете использовать для оценки пропусков / попаданий в кеш / количества передач и тому подобного.
  3. Аналогично 2, очень зависит от системы, которую вы получили. Но если у вас есть многопроцессорная конфигурация, вы можете наблюдать первый протокол согласования кэша (MESI) со вторым.

Вы упомянули WBINVD - afaik, который всегда будет завершен, то есть все строки кэша

0 голосов
/ 07 июля 2011

Возможно, это не ответ на ваш конкретный вопрос, но вы пытались использовать кеш-профилировщик, такой как Cachegrind ?Он может использоваться только для профилирования кода пользовательского пространства, но, тем не менее, вы можете использовать его, например, перемещая код своей функции в пользовательское пространство, если он не зависит от каких-либо специфичных для ядра интерфейсов.

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

...