Читая эти два вопроса , я вижу, что понимание поведения кэширования процессора может быть важным при работе с большими объемами данных в памяти. Я хотел бы понять, как работает кэширование, чтобы добавить еще один инструмент в мой набор инструментов оптимизации.
Каковы основные принципы работы кэша ЦП, чтобы я мог писать код, который использует его разумно? Кроме того, есть ли способ профилировать код, чтобы увидеть, замедляет ли плохое использование кэша?
c
optimization
caching
Тимоти Джонс
источник
источник
Ответы:
источник
Сложность этого вопроса была за пределами человеческого понимания в эти дни. (Так было в течение последних 5 лет.) Объедините это с коротко-векторным параллелизмом (SIMD), и у вас возникнет чувство безнадежности, что оптимизация кода вручную более экономически неосуществима - не то, что это невозможно, но это не быть экономически эффективным больше.
Текущий подход заключается в том, чтобы полагаться на обучение компьютеров тому, как оптимизировать - создавая варианты кода, которые вычисляют одни и те же ответы с различными структурами (циклы, структура данных, алгоритмы) и автоматически оценивая производительность. Правила преобразования кода задаются с помощью очень строгой математической модели, так что это могут понять как ученые, так и компьютеры.
Ниже приведена ссылка, опубликованная Ларри OBrien в одном из его ответов .
http://onward-conference.org/2011/images/Pueschel_2011_AutomaticPerformanceProgramming_Onward11.pdf
источник
Вполне возможно понять и оптимизировать кэши. Это начинается с понимания аппаратного обеспечения и продолжается контролем системы. Чем меньше у вас контроля над системой, тем меньше вероятность успеха. Linux или Windows работают с множеством приложений / потоков, которые не работают.
Большинство кэшей несколько схожи по своим свойствам, используют некоторую часть поля адреса для поиска совпадений, имеют глубину (пути) и ширину (строка кэша). У некоторых есть буферы записи, некоторые могут быть настроены на запись или обход кеша при записи и т. Д.
Вы должны четко осознавать все происходящие транзакции памяти, которые попадают в этот кеш (некоторые системы имеют независимые кеши команд и данных, облегчающие задачу).
Вы можете легко сделать кэш бесполезным, если не будете тщательно управлять своей памятью. Например, если у вас есть несколько блоков данных, которые вы обрабатываете, надеясь сохранить их в кеше, но они находятся в памяти по адресам, которые даже кратны относительно проверки попадания / пропуска кэшей, скажем, 0x10000 0x20000 0x30000, и у вас есть больше Эти способы могут привести к очень быстрому созданию чего-то, что работает довольно медленно при включенном кеше, медленнее, чем при отключенном. Но измените это на 0x10000, 0x21000, 0x32000, и этого может быть достаточно, чтобы в полной мере воспользоваться кешем, уменьшая выселения.
Суть в том, что ключом к оптимизации кеша (ну, кроме того, чтобы хорошо знать систему) является одновременное хранение в кеше всего необходимого для производительности, упорядочение этих данных таким образом, чтобы их можно было получить. все это в кеше сразу. И предотвращение высвобождения значительных частей используемых вами данных такими вещами, как выполнение кода, прерывания и другие регулярные или случайные события.
То же самое касается кода. Однако это немного сложнее, так как вам нужно контролировать места, где находится код, чтобы избежать коллизий с другим кодом, который вы хотите сохранить в кэше. Во время тестирования / профилирования любого кода, который проходит через кеш, добавляющий одну строку кода здесь или там, или даже один nop, все, что перемещает или изменяет адреса, где живет код, от одной компиляции к другой для того же кода, изменяется там, где строки кэша попадают в этот код и изменяют то, что выселяется, а что нет для критических секций.
источник
Оба nwong - х и Майкл Borgwardt в ответ дать хороший совет.
Кроме того, сначала доверьтесь оптимизации компилятора по этим вопросам.
Если вы используете недавний компилятор GCC, вы можете использовать (с экономией) его
__builtin_prefetch
функцию. Смотрите этот ответ на stackoverflow.источник