Почему версии clang так несовместимы с их скоростью? - PullRequest
2 голосов
/ 09 апреля 2020

Я написал эту простую программу (в сумме 9. cpp) для тестирования среды выполнения C ++:

#include <stdio.h>

typedef unsigned long long int big;

constexpr bool has9(big num) {
    while(num != 0) {
        int last = num % 10;
        if(last == 9) {
            return true;
        }
        num /= 10;
    }
    return false;
}

int main(int argc, char* argv[]) {
    if (argc < 2) {
        fprintf(stderr, "Must provide an upper limit.\n");
        return 1;
    }
    big ubound;
    if (sscanf(argv[1], "%llu", &ubound) != 1) {
        fprintf(stderr, "Could not read an integer from argv[1].\n");
    }
    big sum = 0;
    for (big i = 0; i < ubound; ++ i) {
        if (has9(i)) {
            sum += i;
        }
    }
    printf("%llu\n", sum);
    return 0;
}

Я скачал clang 6 и clang 10 с этой страницы . Я скомпилировал файл с clang++-6 -Ofast -march=core2 sum9.cpp -o sum9-c6 и clang++-10 -Ofast -march-core2 sum9.cpp -o sum9-c10. Затем я рассчитал их с time ./sum9-c6 1000000000 и time ./sum9-c10 1000000000. К моему удивлению, у clang 6 было в среднем 8,65 секунды, в то время как у Clang-10 было в среднем 9,74 секунды. Для справки, эквивалентная программа ржавчины занимает около 8,57 секунд при компиляции с -C target-cpu=core2. Однако, когда я компилирую с -march=native вместо -march=core2, clang 10 неожиданно запускается всего за 8,09 секунды, а clang 6 - 8,28 секунды. Почему это происходит, и можно ли сделать так, чтобы clang 10 не занимал так много времени, когда не используется -march=native?

Вот версии:

clang version 10.0.0 
Target: x86_64-unknown-linux-gnu
Thread model: posix
clang version 6.0.1 (tags/RELEASE_601/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix

Здесь постоянно выполняются тесты для clang10 и clang6 с -march=core2:

clang10
real    0m9.738s

clang6
real    0m8.561s

clang10
real    0m9.732s

clang6
real    0m8.553s

clang10
real    0m9.737s

clang6
real    0m8.582s

clang10
real    0m9.741s

clang6
real    0m8.579s

clang10
real    0m9.736s

clang6
real    0m8.582s

clang10
real    0m9.736s

clang6
real    0m8.580s

clang10
real    0m9.738s

clang6
real    0m8.564s

clang10
real    0m9.725s

clang6
real    0m8.569s

clang10
real    0m9.729s

clang6
real    0m8.559s

clang10
real    0m9.730s

clang6
real    0m8.574s

Вот тесты для -march=native (обратите внимание, что clang10 теперь неожиданно быстрее):

clang10
real    0m8.09s

clang6
real    0m8.28s

clang10
real    0m8.09s

clang6
real    0m8.28s

clang10
real    0m8.08s

clang6
real    0m8.27s

clang10
real    0m8.09s

clang6
real    0m8.27s

clang10
real    0m8.07s

clang6
real    0m8.27s

clang10
real    0m8.08s

clang6
real    0m8.28s

clang10
real    0m8.08s

clang6
real    0m8.27s

clang10
real    0m8.09s

clang6
real    0m8.29s

clang10
real    0m8.08s

clang6
real    0m8.28s

clang10
real    0m8.07s

clang6
real    0m8.27s
...