Создание масштабируемого локального кэша приложений имеет первостепенное значение для скорости вашего приложения. Принципы хорошо объясняются Скоттом Мейерсом . Неизменность не очень хорошо работает с локальностью кэша, поскольку вы создаете новые объекты в памяти, что заставляет ЦП снова загружать данные из нового объекта.
Как отмечается в докладе, даже на современных процессорах кэш-память L1 имеет размер всего 32 КБ, который распределяется для кода и данных между всеми ядрами. Если вы используете многопоточность, вы должны стараться использовать как можно меньше памяти (до свидания, всегда), чтобы оставаться в самом быстром кеше. Кэш-память второго уровня составляет около 4–8 МБ, что намного больше, но все же крошечно по сравнению с данными, которые вы пытаетесь отсортировать.
Если вам удастся написать приложение, которое потребляет как можно меньше памяти (локальность кэша данных), вы можете получить ускорение 20 или более. Но если вы справитесь с этим для 1 ядра, вполне возможно, что масштабирование на большее количество ядер снизит производительность, поскольку все ядра конкурируют за один и тот же кэш L2.
Чтобы получить максимальную отдачу от этого, ребята из C ++ используют PGA (Profile Guided Optimizations), которая позволяет им профилировать свое приложение, которое используется в качестве входных данных для компилятора, чтобы испускать более оптимизированный код для конкретного случая использования.
Вы можете в определенной степени улучшить управляемый код, но поскольку на локальность кэша влияет очень много факторов, маловероятно, что в реальном мире вы когда-нибудь увидите ускорение на 20 из-за общей локализации кэша. Это остается режимом C ++ и компиляторами, которые используют данные профилирования.