2015-03-15 3 views
0

Недавно я заметил, что в проекте, где у меня есть несколько исходных файлов (file1.cpp, file2.cpp, ...), это может повлиять на функцию времени выполнения A, которая будет называться другой функцией B, определяется в том же исходном файле, что и функция B, или нет.В каком исходном файле я должен определить функцию

В моем случае, когда оба определены в одном file1.cpp, функция B занимает около 90% времени выполнения, а анализ профайлера не возвращает время выполнения для функции A (называется B).

НО, если они определены в разделенных файлах, время выполнения увеличивается в ~ 150%, а функция A занимает ~ 65% времени, а B - всего ~ 25 (всего около 90%).

Почему время выполнения увеличено? Имеет ли функция defitinion местоположение влияние на то, как они называются? Я не могу понять.

На этом этапе я должен сказать, что я использую уровень оптимизации 3, поэтому в обоих случаях функция A должна быть встроена в B.

EDIT: Я использую Linux Ubuntu 14.04, anf компилирую с помощью g++ и следующих флагов: -O3 -pg -ggdb -Wall -Wextra -std=c++11.

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

A:

size_t A (const Matrix& P, size_t ID) { 
    size_t j(0); 
    while (P[j][0]!=ID) { 
    ++j; 
    } 
    return j; 
} 

B:

Matrix B (const Matrix& P, const Matrix& O, Matrix* pREL, double d, const Vector& f) {` 

    size_t length (O.size())  ; 
    Matrix oREL (*pREL) ; 

    for (size_t i(0); i<length; ++i) { 
    for (size_t j(0); j<=i; ++j) { 
    double fi(f[O[i][0]-1]); 
    if (f.size()==1) fi = 0.0; 
    if (i!=j) { 
     double gAC, gAD, gBC, gBD, fj(f[O[j][0]-1]); 
     if (f.size()==1) fj = 0.0; 
     gAC = C(pREL,P,O,i,j,dcol,dcol); 
     gAD = C(pREL,P,O,i,j,dcol,scol); 
     gBC = C(pREL,P,O,i,j,scol,dcol); 
     gBD = C(pREL,P,O,i,j,scol,scol); 
     oREL[i][j] = 0.25 * (gAC + gAD + gBC + gBD) 
          * (1 - d*(fi+fj));       
    } else if (i==j) oREL[i][i] = 0.5 * (1.0+C(pREL,P,O,i,i,dcol,scol)) 
             * (1.0-2.0*d*fi);   
    } 
} 

    delete pREL; 

    return oREL; 
} 

C:

coefficient C (Matrix * pREL, const Matrix& P, const Matrix& O, 
        size_t coord1, size_t coord2, unsigned p1, unsigned p2) { 
double g; 
size_t i, j ; 
i = A(P,O[coord1][p1]); 
j = A(P,O[coord2][p2]); 
if (i<=j) g = (*pREL)[j][i]; 
if (i>j) g = (*pREL)[i][j]; 

return g; 
} 
+3

Возможно, из-за вставки. Без цельной оптимизации программы вы получаете только встраивание тех вызовов функций, где определение функции известно в блоке перевода вызова. –

+1

Какой компилятор и операционная система и компьютер вы используете? Какие флаги оптимизации вы даете?Показать исходный код, связанный с проблемой (например, функция A и функция B). Измените свой вопрос, чтобы улучшить его. –

ответ

1

Да. Компилятор может только встроить функцию, когда он знает определение функции в точке вставки. Он может и не знать этого, если вы поместите его в другой блок компиляции. В вашем случае я бы предположил, что компилятор «думает»: он вызывает эту функцию, но я не знаю, где она еще, поэтому я делаю обычный звонок и позволяю компоновщику беспокоиться об этом позже.

По этой причине код, который должен быть встроен, очень часто помещается в заголовочные файлы.

+0

Написание функции A в файле заголовка исходного кода, содержащего B ('B.h'), решает проблему, как ее написание в' B.cpp'. Почему мы предпочитаем писать его в заголовочном файле? Кстати, может быть, я что-то пропустил, но просто написание 'inline' перед объявлением функции не решает проблему. На самом деле программа не компилируется. В любом случае, этот комментарий был очень полезен, спасибо! – EuGENE

+0

Прежде всего, 'inline' - всего лишь подсказка для компилятора. Больше ничего. Подсказка может быть проигнорирована и, безусловно, будет проигнорирована, если компилятор не сможет встроить код. Компилятор, конечно же, не будет встроенным кодом, доступным только на этапе компоновки. Во-вторых, я не говорю, что вам следует предпочесть помещать реализацию в заголовочные файлы в целом, но в конкретных случаях. В частности, когда у вас есть методы шаблонов или когда вы ожидаете, что какой-либо код всегда будет инкрустирован по соображениям производительности. – ezaquarii

0

Во-первых, когда вы заботитесь о производительности и бенчмаркинге, вы должны включить optimizations в свой компилятор.

Я предполагаю, что вы используете GCC на Linux, поэтому вы компилируете с помощью g++.

Вы должны скомпилировать с g++ -Wall -O2, если вам интересно.

Вы можете включить путем составления и связывая с g++ -Wall -O2 -flto

Конечно, вы можете использовать -O3 вместо -O2

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