Как очистить диапазон адресов в кэше процессора? - PullRequest
5 голосов
/ 08 мая 2019

Я хочу проверить производительность пользовательской программы в linux, работающей на x86.Чтобы рассчитать производительность, мне необходимо сбросить определенные строки кэша в память (убедитесь, что эти строки недействительны и при следующем запросе произойдет пропуск кэша).

Я уже видел предложения по использованиюcacheflush (2), который должен быть системным вызовом, но g ++ жалуется, что он не объявлен.Кроме того, я не могу использовать clflush_cache_range, который, очевидно, может быть вызван только в программе ядра.Сейчас я попытался использовать следующий код:

static inline void clflush(volatile void *__p)
{
    asm volatile("clflush %0" : "+m" (*(volatile char __force *)__p));
}

Но это приводит к следующей ошибке при компиляции:

ошибка: ожидаемое первичное выражение до 'volatile'

Затем я изменил его следующим образом:

static inline void clflush(volatile void *__p)
{
    asm volatile("clflush %0" :: "m" (__p));
}

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

1 Ответ

2 голосов
/ 08 мая 2019

Второй сбрасывает память, содержащую указатель __p, который находится в стеке, поэтому он не дает желаемого эффекта.

Проблема с первым состоит в том, что он использует макрос __force, который определен в ядре Linux и здесь не нужен. ( Что делает __atribute __ ((force))? )

Если вы удалите __force, он будет делать то, что вы хотите.

(Вам также следует изменить его, чтобы не использовать имя переменной __p, которая является зарезервированным идентификатором.)

...