Мы делаем llvm::libc, и тут есть забавная история. Достаточно понятно, что в libc самые используемые функции на проде это memcpy, memcmp, memmove, strlen и тд, те, которые работают с памятью, так как они встречаются в векторах/строках и тд. Я сотню раз видел посты, где люди ускоряли эти функции для больших значений, мол, смотрите, мой memcmp работает быстрее на сотню мегабайт в секунду или поиск символа на пару десятков.



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



Мы решили опубликовать распределения разных workload'ов у таких функций. Посмотреть их можно здесь. Но если проанализировать в среднем, до 128 байт где-то 99% вызовов, остальное очень редкое. Учитывая это, для оптимального перформанса таких функций, лучше уметь в Profile Guided Optimization, который понимает, что можно во многих местах кода инлайнить маленькие отрезки. Отчасти поэтому мы в Google и решили делать libc со статической линковкой, потому что динамика не позволяет проворачивать пост компиляторные оптимизации. А все SIMD развороты циклов намного меньше решают.



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



1. Если у вас поисковый шард -- это правда, кеш надо прогреть

2. Если у вас табличка для конвертации 2 байт в десятичное представление, ваша программа вряд ли только и конвертирует. Тру стори, ругался очень долго, что это плохо, но забил, так как там маленькая opportunity.



И в целом мой совет -- если вы видите какой-то бенчмарк, который зависит от данных, и ну уж очень важен, или вы хотите продемонстрировать, что что-то ускорили, имейте в виду и проверяйте несколько вещей:



1. Всякие табличные значения очень хорошо идут в кеш

2. Branch predictor очень хорошо обучается, какое распределение данных вы даёте функции/программе? Можете ли вы дать лучше/ближе к реальности?



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



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



Но это дало понимание, что никогда, ни в коем случае не делать региональные/факторные распределения документов по шардам в больших системах. Эта штука закончится неоднородными решениями в том числе из-за перфа. Региональные кеши -- ок, региональные last resort базы -- нет, спасибо. Как можно равномернее распределять лучше всего.



Другой пример:



В SimdJson очень много используются таблички. В бенчмарках они очень прогретые в L1 кешах. Интересно сколько перфа теряется, когда эти таблицы привносят кеш миссы. Это прекрасная идея для поста, чтобы так поубавить градус фразы "Парсим X гигабайт в секунду". Я ставлю минимум 5-10% теряется, что в целом, не велика потеря, но не даёт полной картины реального мира.



Поэтому в оптимизациях я люблю branch free code, потому что о бранчах в горячих местах порой сложно спекулировать.



Ещё вот в наших гугловских хэштаблицах есть бенчмарки с суффиксом _Hot/_Cold. К сожалению, померить распределение прогретости достаточно тяжело, но это хотя бы что-то, что помогает не оверфититься по кешам.



Как вариант посмотреть для SimdJson -- вытащить таблицы из глобальной памяти и поместить их в динамическую, сделать cold benchmark (создаются тысячи инстансов класса и десереализует случайный).



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