2013-03-09 3 views
2

Предположим, я хочу сравнить две конкурирующие реализации некоторой функции double a(double b, double c). У меня уже есть большой array <double, 1000000> vals, из которых я могу принимать входные значения, так что мой бенчмаркинг будет выглядеть примерно так:Как заставить компилятор не пропускать мои вызовы функций?

//start timer here 
double r; 
for (int i = 0; i < 1000000; i+=2) { 
    r = a(vals[i], vals[i+1]); 
} 
//stop timer here 

Теперь, умный компилятор может понять, что я могу только когда-либо использовать результат последней итерации просто убейте остальных, оставив меня с double r = a(vals[999998], vals[999999]). Это, конечно, побеждает цель бенчмаркинга.

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

(я видел другие темы, о вставке пустых asm блоков, но я боюсь, что может предотвратить встраивание или переназначение. Я тоже не особо любит идею сложения результатов sum += r; во время каждой итерации, потому что это дополнительная работа, не следует включать в результирующие тайминги. Для целей этого вопроса было бы замечательно, если бы мы могли сосредоточиться на других альтернативных решениях, хотя для всех, кто интересуется этим, есть оживленная дискуссия в комментариях, где консенсусом является то, что += является наиболее подходящим методом во многих случаях.)

+0

Зачем вам это нужно? –

+0

Потому что у меня есть две разные реализации 'a', и я хочу их сравнить. – us2012

+0

Переупорядочение обычно выполняется как оптимизация, afaik. –

ответ

3

Положить a в отдельную блокку и сделать нет использование LTO (оптимизация времени соединения). Таким образом:

  • Цикл всегда одинакова (без разницы за счет оптимизации на основе a)
  • Накладные вызова функции всегда одинакова
  • Для измерения чистого накладных расходов и иметь базовый уровень для сравнения реализаций, только тест пустой версия a

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


Совершенно другой подход может использовать RDTSC, который является аппаратным регистром в ядре процессора, который измеряет тактовые циклы. Это иногда полезно для микро-тестов, но не совсем просто понять результаты правильно. Например, проверьте this и просмотрите/просмотрите SO для получения дополнительной информации о RDTSC.

+0

Это предотвратит встраивание, хотя, нет? – us2012

+0

Да, так как без LTO компилятор не может встроить метод из одного TU в другой TU. –

+0

@ us2012: Добавлено RDTSC, может быть, это вариант/идея для вас? –

Смежные вопросы