Уменьшение промахов в кеше за счет хорошего дизайна

Как уменьшить количество возможных промахов кеша при разработке программы на C++?

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
22
0
9 649
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

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

Такой вид оптимизации зависит от аппаратной архитектуры, поэтому лучше использовать профилировщик для конкретной платформы, например Intel VTune, для обнаружения возможных проблем с кешем.

Для операций с привязкой к данным

  1. использовать массивы и векторы вместо списков, карт и наборов

  2. обрабатывать по строкам по столбцам

Хороший разговор Саттера. Слайды доступны здесь, что неплохо иметь рядом с видео, так как его качество немного ужасное. nwcpp.org/Downloads/2007/Machine_Architecture_-_NWCPP.pdf

Zoomulator 18.01.2012 03:01

Ссылка на видео и слайды презентации мертвы. Порекомендуйте отредактировать комментарии и ответ, включив заголовок видео, чтобы люди могли его найти.

chutsu 02.09.2019 20:44

Избегайте использования динамической памяти, когда в этом нет необходимости. Использование новых, удаленных, интеллектуальных указателей и т. д. Имеет тенденцию распространять данные вашей программы по памяти. Это не хорошо. Если вы можете хранить большую часть своих данных вместе (например, объявляя объекты в стеке), ваш кеш наверняка будет работать намного лучше.

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

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

Немного устарел, но в «Черной книге по программированию графики» Майка Абраша все еще есть много хороших общих советов.

Ответ принят как подходящий

Вот некоторые вещи, которые мне нравится учитывать при работе с таким кодом.

  • Подумайте, хотите ли вы «структуры массивов» или «массивы структур». То, что вы хотите использовать, будет зависеть от каждой части данных.
  • Старайтесь, чтобы структуры были кратными 32 байтам, чтобы они равномерно упаковывали строки кэша.
  • Разделите данные на «горячие» и «холодные» элементы. Если у вас есть массив объектов класса o, и вы часто используете ox, oy, oz вместе, но только изредка нуждаетесь в доступе к oi, oj, ok, тогда подумайте о том, чтобы сложить ox, oy и oz вместе и переместить i, j и k частей в параллельную подмышечную структуру данных.
  • Если у вас есть многомерные массивы данных, то при обычном порядке расположения строк доступ будет очень быстрым при сканировании по предпочтительному измерению и очень медленным по другим. Сопоставление его с заполнениеизгиб вместо этого поможет сбалансировать скорости доступа при перемещении в любом измерении. (Техники блокировки аналогичны - они просто Z-порядок с большим основанием.)
  • Если вы должны столкнуться с ошибкой кеширования, постарайтесь как можно больше использовать эти данные, чтобы амортизировать стоимость.
  • Вы делаете что-нибудь многопоточное? Остерегайтесь замедления из-за протоколов согласованности кеша. Заполните флаги и маленькие счетчики, чтобы они находились в отдельных строках кэша.
  • SSE на Intel предоставляет некоторые встроенные функции предварительной выборки, если вы заранее знаете, к чему будете получать доступ.

+1. Идея кривой Гильберта очень нова, откуда вы ее взяли? Действительно ли время, необходимое для преобразования между координатами кривой Гильберта и координатами стандартного массива, стоит эффективности кеширования, или оно того стоит, только если вы выполняете преобразование координат в одном направлении, но не в другом?

user334911 16.11.2012 04:34

Также, если вы используете C++ и многопоточность, вам необходимо учитывать ложное совместное использование, локальность и горячие данные в кеше каждого процессора. Это может иметь большое значение. Также, особенно в многопоточных вычислениях, методы LIFO более эффективны, чем вычисления в режиме FIFO, но они также действительны в однопроцессорной архитектуре.

Другие вопросы по теме