Одна вещь, которую вы можете сделать, - это вызвать функцию с большим количеством кода и получить доступ к большому количеству памяти между вызовами элемента, который вы профилируете. Например, в псевдокоде (быть в основном от языка):
// loop some number of times
{
//start timing
profile_func();
//stop timing
//add to total time
large_func(); // Uses lots of memory and has lots of code
}
// Compute time of profile func by dividing number of iterations by total time
Код в large_func() может быть нонсенс код, как некоторый набор опс повторяется снова и снова. Ключ в том, что он или его код не оптимизируются при компиляции, так что он фактически очищает кеши кода и данных CPU (а также кеши L2 и L3 (если есть)).
Это очень важный тест для многих случаев. Причина в том, что небольшие быстрые функции, которые часто профилируются изолированно, могут работать очень быстро, используя преимущества кэша CPU, встраивания и регистрации. Но часто в больших приложениях эти преимущества отсутствуют, из-за контекста, в котором эти быстрые функции называются.
В качестве примера, просто профилирование функции путем ее запуска на миллион итераций в узком цикле может показать, что функция выполняется в течение 50 наносекунд. Затем вы запускаете его, используя фреймворк, который я показал выше, и внезапно его время работы может резко увеличиться до микросекунд, поскольку оно больше не может использовать тот факт, что у него есть весь процессор - его регистры и кеши, сам по себе.
Без кэширования производительность часто будет ужасной. Я бы скорее попытался измерить репрезентативные рабочие нагрузки на репрезентативных (т.е. кеширующих) платформах. –
Вы хотите время от времени удалять кеш, как указывает объект? Или вы хотите полностью отключить кеш, как сам вопрос? –
Я хочу, чтобы функции выполнялись справедливо. Это все. Если func1 не кэшируется, func2 также нельзя кэшировать. Если func1 вызывает ошибки страницы, функция func2 тоже. Конечно, я хочу, чтобы оба они не вызывали ошибку страницы. – Benjamin