Как пометить некоторые диапазоны памяти как не кешируемые из C ++? - PullRequest
16 голосов
/ 03 марта 2012

Я читал википедию о кеше процессора здесь: http://en.wikipedia.org/wiki/CPU_cache#Replacement_Policies

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

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

Кроме того, я был бы признателен за ресурсы о том, как улучшить производительность кеша, особенно в C ++, даже если они не используют никаких функций, которые непосредственно связаны с кешами ЦП. Например, мне интересно, если использование чрезмерных уровней косвенности (например, контейнер указателей на контейнеры указателей) может повредить производительность кэша.

Ответы [ 4 ]

6 голосов
/ 03 марта 2012

В Windows вы можете использовать VirtualProtect(ptr, length, PAGE_NOCACHE, &oldFlags), чтобы установить режим кэширования для памяти, чтобы избежать кэширования.

Относительно слишком большого количества косвенных адресов: Да, они могут повредить производительность кэша, если выочень часто обращаются к различным частям памяти (что обычно и происходит).Тем не менее, важно отметить, что если вы последовательно разыменовываете набор того же , например, из 8 блоков памяти, и отличается только 9-й блок, то это, как правило, не будет иметь значенияпотому что 8 блоков будут кэшироваться после первого доступа.

5 голосов
/ 03 марта 2012

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

Как программист, обычно работающий с платформами x86, отличными от Windows, эта статья о встроенных функциях GCC для x86 и x86-64 , вероятно, наиболее полезна.

5 голосов
/ 03 марта 2012

Практическое правило для оптимизации доступа к кешу: кластер вместе загружает и сохраняет на один и тот же адрес . Например, следующий код:

for (size_t i=0; i<A.size(); ++i)
  B[i] = func1(A[i]);

for (size_t i=0; i<A.size(); ++i)
  C[i] = func2(A[i]);

Может быть оптимизирован для более эффективного доступа к кешу:

for (size_t i=0; i<A.size(); ++i) {
  B[i] = func1(A[i]); // A[i] is fetched to the cache
  C[i] = func2(A[i]); // Good chance that A[i] remains in the cache
}

Современные процессоры довольно хорошо предсказывают доступ к памяти с помощью регулярных шаблонов в циклах и способны предварительно выбирать память для кэширования и ускорения выполнения. Таким образом, еще одно практическое правило: предпочтительнее использовать std :: vector и std :: array, чем другие контейнеры .

4 голосов
/ 03 марта 2012
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...