Будет ли компилятор C ++ встроить цикл for с небольшим количеством терминов? - PullRequest
0 голосов
/ 31 марта 2019

Предположим, у меня есть класс Matrix5x5 (с соответственно перегруженными индексными операторами), и я пишу метод trace для вычисления суммы его диагональных элементов:

double Matrix5x5::trace(void){
    double t(0.0);
    for(int i(0); i <= 4; ++i){
        t += (*this)[i][i];
    }
    return t;
}

Конечно, если я вместо этогописал (а):

return (*this)[0][0]+(*this)[1][1]+(*this)[2][2]+(*this)[3][3]+(*this)[4][4];

тогда я бы точно избежал накладных расходов по объявлению и увеличению моей переменной i.Но было бы глупо выписывать все эти термины!

Поскольку в моем цикле содержится constexpr количество терминов, которые оказываются достаточно малыми, будет ли компилятор встроен для меня?

Ответы [ 2 ]

1 голос
/ 31 марта 2019

Да! GCC делает это на уровне оптимизации -O1 и выше, а clang делает это на уровне оптимизации -O2 и выше.

Я проверил это, используя этот код:

struct Matrix5x5 {
    double values[5][5];
    Matrix5x5() : values() {}

    double trace() {
        double sum = 0.0;
        for(int i = 0; i < 5; i++) {
            sum += values[i][i]; 
        }
        return sum; 
    }
};

double trace_of(Matrix5x5& m) {
    return m.trace(); 
}

И это сборка, созданная gcc и clang:

trace_of(Matrix5x5&):
    pxor    xmm0, xmm0
    addsd   xmm0, QWORD PTR [rdi]
    addsd   xmm0, QWORD PTR [rdi+48]
    addsd   xmm0, QWORD PTR [rdi+96]
    addsd   xmm0, QWORD PTR [rdi+144]
    addsd   xmm0, QWORD PTR [rdi+192]
    ret

Вы можете поиграться с кодом и посмотреть соответствующую сборку здесь: https://godbolt.org/z/p2uF0E.

Если вы перегрузите operator[], вам придется повысить уровень оптимизации до -O3, но компилятор все равно сделает это: https://godbolt.org/z/JInIME

1 голос
/ 31 марта 2019

Если ваш компилятор достаточно умен, он может оптимизировать этот случай с помощью как-бы правила . Таким образом, компилятор C ++ может оптимизировать многие вещи. Но это также не может. Единственный способ быть абсолютно уверенным - это проверить код, сгенерированный вашим конкретным компилятором. При этом вряд ли это станет узким местом в вашей программе. Так что делайте, какая версия будет более читабельной.

...