Первый вызов функции C медленнее, чем последующие вызовы [дубликаты]

Я пытаюсь аппроксимировать накладные расходы на вызов функции в C. Итак, у меня есть пустая функция с атрибутом((optimize("O0"))), так что GCC не оптимизирует ее.

int __attribute__((optimize("O0"))) func(int a)
{
    return (a+a);
}

Я использую метод, описанный в документе http://www.intel.com/content/www/us/en/embedded/training/ia-32-ia-64-benchmark-code-execution-paper.html для определения времени, так что это довольно точно.

Поэтому я вызываю функцию в цикле несколько раз и измеряю время выполнения:

for (i = 0; i < 10; i++)
{
    t1 = start_timer();
    x = func(i);
    t2 = end_timer();

    time = t2 - t1;
}

Я заметил, что при первом вызове функции (i=0) требуется больше циклов (~10x), чем при последующих вызовах. Почему это происходит?


person AbhinavChoudhury    schedule 18.09.2016    source источник
comment
Кэширование. При первом вызове функции ее инструкции не будут находиться в кеше.   -  person PSkocik    schedule 19.09.2016
comment
Если вы компилируете с параметром -fpic или -fPIC, а символ функции имеет видимость по умолчанию, также будут возникать накладные расходы при первом вызове, связанные с поиском символа в DSO.   -  person PSkocik    schedule 19.09.2016
comment
Ульрих Дреппер подробно рассматривает обе проблемы в akkadia.org/drepper/cpumemory.pdf и в akkadia.org/drepper/dsohowto.pdf.   -  person PSkocik    schedule 19.09.2016
comment
Может быть все что угодно, от позднего связывания до перегрева DRAM, при этом зависает на короткое время (да, современные системы могут так делать), ретрансляция по мостам, буферизация, кеш, погода, космические лучи, комические лучи, ray ban и т.д.   -  person too honest for this site    schedule 19.09.2016
comment
Почему бы вам не переместить метки таймера t1 и t2 за пределы цикла, а затем разделить время на 10?   -  person Weather Vane    schedule 19.09.2016