Есть ли способ точно определить, какие значения, адреса памяти и / или другая информация в настоящее время находятся в кэше ЦП (L1, L2 и т. Д.) — для текущих или всех процессов?
Я довольно много читал о том, как оптимизировать программы для более эффективного использования кэша ЦП. Тем не менее, я ищу способ действительно определить, являются ли определенные подходы эффективными.
Нижняя линия: можно ли быть 100% уверен что делает и не делает это в кеш процессора.
Поиск по этой теме возвращает несколько результатов о том, как определить размер кэша, но не его содержимое.
Редактировать: Чтобы прояснить некоторые из комментариев ниже: Поскольку программное обеспечение, несомненно, изменяет кэш, имеют ли производители ЦП систему встроенного диагностического инструмента / аппаратного обеспечения, которая обеспечивает эту функциональность?
Если у вас относительно современный процессор под управлением Windows, взгляните на
http://software.intel.com/en-us/articles/intel-performance-counter-monitor-a-better-way-to-measure-cpu-utilization
и посмотрите, может ли это дать вам то, что вы ищете.
Без использования специального оборудования вы не сможете напрямую проверить, что находится в кэше ЦП. Запуск любого программного обеспечения для проверки кэша ЦП изменит его состояние.
Наилучший подход, который я нашел, — это просто определить реальные горячие точки в вашем приложении и сравнить альтернативные алгоритмы на оборудовании, на котором будет выполняться код в производственной среде (или на ряде вероятного оборудования, если у вас нет контроля над производственной средой).
В дополнение к ответу Эрика Дж. Я добавлю, что, хотя я уверен, что у крупных производителей микросхем есть такие инструменты, маловероятно, что такое средство «отладки» будет доступно обычным смертным, таким как вы и я, но даже если бы это было действительно оказать большую помощь
Зачем? Маловероятно, что у вас возникают проблемы с производительностью, которые вы проследили в кеше и которые не могут быть решены с помощью хорошо известных и «здравых смыслов» методов для поддержания высоких коэффициентов попадания в кэш.
Есть ли у вас действительно Оптимизированы ли все остальные горячие точки в коде и плохое поведение кеша процессором? Я очень сильно сомневаюсь в этом.
Дополнительно, как пища для размышлений: действительно Хотите оптимизировать поведение вашей программы только для одного или двух конкретных процессоров? В конце концов, алгоритмы кеширования постоянно меняются, как и параметры кеширования, иногда резко.
Оптимизация для одного конкретного размера кэша ЦП обычно тщетна, так как эта оптимизация потерпит неудачу, если ваши предположения о размерах кэша ЦП неверны при выполнении на другом ЦП.
Но выход есть. Вам следует оптимизировать определенные шаблоны доступа, чтобы процессор мог легко предсказать, какие области памяти следует читать далее (наиболее очевидным является линейное увеличение чтения). Чтобы иметь возможность полностью использовать процессор, вы должны прочитать о тайник забыт алгоритмы, в которых большинство из них следуют стратегии «разделяй и властвуй», где проблема в определенной степени разделяется на части, пока все обращения к памяти полностью не уместятся в кэш ЦП.
Также стоит упомянуть, что у вас есть кэш кода и данных, которые разделены. Херб Саттер имеет хороший видео онлайн, где он подробно рассказывает о внутренностях процессора.
Visual Studio Profiler может собирать счетчики процессора, имеющие дело с памятью и счетчиками L2. Эти параметры доступны при выборе профилирования инструментов.
Intel также имеет бумага онлайн, которая более подробно рассказывает об этих счетчиках ЦП и о том, что показывает диспетчер задач Windows и Linux, и о том, как это неправильно для современных ЦП, которые работают внутренне асинхронно и параллельно на многих разных уровнях. К сожалению, от Intel нет инструмента для непосредственного отображения этого материала. Единственный инструмент, который я знаю, это профилировщик VS. Возможно, VTune имеет аналогичные возможности.
Если вы зашли так далеко, чтобы оптимизировать свой код, вы могли бы обратить внимание и на программирование на GPU. Вам нужен как минимум PHD, чтобы разобраться с инструкциями SIMD, месторасположением кеша, … чтобы получить в 5 раз больше, чем ваш первоначальный дизайн. Но, перенося ваш алгоритм на графический процессор, вы получаете коэффициент 100 с гораздо меньшими усилиями, чем приличная видеокарта. Графические процессоры NVidia, которые поддерживают CUDA (все проданные сегодня карты поддерживают это) могут быть очень хорошо запрограммированы на диалекте C. Есть даже обертка для управляемого кода (.NET), позволяющая использовать все возможности графических процессоров.
Вы можете оставаться независимым от платформы, используя OpenCL но поддержка NVidia OpenCL очень плохая. Драйверы OpenCL как минимум в 8 раз медленнее, чем его аналог CUDA.
Почти все, что вы делаете, будет в кеше в тот момент, когда вы его используете, если только вы не читаете память, которая была сконфигурирована как «не кешируемая» — как правило, это память кадрового буфера вашей видеокарты. Другой способ «не попасть в кеш» — использовать определенные инструкции загрузки и сохранения, которые не являются «временными». Все остальное считывается в кэш L1 до того, как оно достигает целевых регистров внутри самого ЦП.
Практически во всех случаях у процессоров есть довольно хорошая система знания того, что хранить и что выбрасывать в кеш, а кеш почти всегда «полон» — не обязательно полезных вещей, если, например, вы работаете со своим через огромный массив, он будет просто содержать много «старого массива» [именно здесь «невременные» операции с памятью пригодятся, поскольку они позволяют вам читать и / или записывать данные, которые не будут сохранены в кеше, так как в следующий раз вы вернетесь к той же точке, его не будет в любом месте].
И да, у процессоров обычно есть специальные регистры [которые могут быть доступны в драйверах ядра], которые могут проверять содержимое кэша. Но их довольно сложно использовать без потери содержимого кеша. И они определенно бесполезны как проверка типа «сколько массива A в кэше». Они специально для «Хм, похоже, что строка кэша 1234 повреждена, я бы лучше прочитал кэшированные данные, чтобы увидеть, действительно ли это значение, которое должно быть», когда процессоры не работают должным образом.
Как говорит DanS, есть счетчики производительности, которые вы можете прочитать из подходящего программного обеспечения [чтобы использовать эти регистры в ядре, вам также нужно какое-то «драйверное» программное обеспечение]. В Linux есть «perf». А у AMD есть аналогичный набор счетчиков производительности, который можно использовать, чтобы выяснить, например, «сколько промахов в кеше было у нас за этот период времени» или «сколько обращений к кешу в L» было у нас и т. Д.