Уменьшение промахов в кеше через хороший дизайн
Как уменьшить количество возможных промахов кеша при разработке программы на С++?
Поддерживаются ли функции вставки каждый раз? или это хорошо только тогда, когда программа ограничена ЦП (т.е. программа ориентирована на вычисление не ориентированной на В/В)?
Ответы
Ответ 1
Вот некоторые вещи, которые мне нравятся при работе над этим типом кода.
- Рассмотрим, хотите ли вы "структуры массивов" или "массивы структур". То, что вы хотите использовать, будет зависеть от каждой части данных.
- Постарайтесь, чтобы структуры умножились на 32 байта, чтобы они равномерно упаковывали строки кэша.
- Разделите свои данные в горячих и холодных элементах. Если у вас есть массив объектов класса o, и вы часто используете ox, oy, oz, но только изредка должны обращаться к oi, oj, ok, тогда подумайте о том, чтобы объединить ox, oy и oz и перемещать i, j и k частей к параллельной структуре подмышечных данных.
- Если у вас многомерные массивы данных, то с обычными макетами порядка строк, доступ будет очень быстрым при сканировании вдоль предпочтительного размера и очень медленном по сравнению с другими. Сопоставление его по заполнению пространства curve вместо этого будет помогают балансировать скорости доступа при перемещении в любом измерении. (Методы блокировки похожи - они всего лишь Z-порядок с большим радиусом.)
- Если вы должны понести недостаток в кеше, попробуйте сделать как можно больше с этими данными, чтобы амортизировать затраты.
- Вы делаете что-нибудь многопоточное? Следите за замедлением от протоколов согласования кеша. Пэд-флаги и маленькие счетчики, чтобы они были в отдельных строках кэша.
- SSE на Intel предоставляет некоторые встроенные функции предварительной выборки, если вы знаете, к чему вы будете достаточно далеко заблаговременно.
Ответ 2
Для операций с данными
использовать массивы & векторы над списками, картами и наборы
обрабатывать строки по столбцам
Ответ 3
Разрешить CPU для предварительной выборки данных. Например, вы можете уменьшить пропуски в кеш-памяти, обрабатывая многомерные массивы по строкам, а не по столбцам, циклам разворота и т.д.
Такая оптимизация зависит от аппаратной архитектуры, поэтому вам лучше использовать какой-то профилировщик платформы, такой как Intel VTune, для обнаружения возможных проблем с кешем.
Ответ 4
Выполнение функций инкрустации может нанести вред кэшу команд. И если память не привязана к выборке, то вряд ли это приведет к значительной (если таковой) разнице.
Как всегда, любая оптимизация должна быть проинформирована профилированием, а не хаками. Не говоря уже о том, что вам нужно будет понять, что говорит вам профайлер, что подразумевает знакомство с языком ассемблера и конкретными характеристиками планшета, для которого вы оптимизируете.
Немного устарел, но Майк Абраш "Черная книга графического программирования" по-прежнему имеет множество хороших общих советов.
Ответ 5
Также, если вы выполняете С++ и многопоточность, вам нужно учитывать ложный доступ, локальность и горячие данные в кеше каждого процессора. Это может иметь большое значение. Кроме того, особенно в многопоточных вычислениях вещи в режиме LIFO более эффективны, чем вычисления в режиме FIFO, но также и в однопроцессорной архитектуре.
Ответ 6
Избегайте использования динамической памяти, когда это не необходимо. Использование новых, удаленных, интеллектуальных указателей и т.д. Имеет тенденцию распространять ваши программные данные по всей памяти. Это нехорошо. Если вы можете сохранить большую часть своих данных (например, объявив объекты в стеке), ваш кеш, безусловно, будет работать намного лучше.