Почему std::inner_product медленнее, чем наивная реализация?

Это моя наивная реализация точечного продукта:

float simple_dot(int N, float *A, float *B) {
    float dot = 0;
    for(int i = 0; i < N; ++i) {
    dot += A[i] * B[i];
    }

    return dot;
}

И это с помощью библиотеки C++:

float library_dot(int N, float *A, float *B) {
    return std::inner_product(A, A+N, B, 0);
}

Я запустил какой-то тест (код здесь https://github.com/ijklr/sse), и версия библиотеки намного медленнее. Мой флаг компилятора -Ofast -march=native

1 ответ

Решение

Ваши две функции не делают одно и то же. Алгоритм использует аккумулятор, тип которого выводится из начального значения, которое в вашем случае (0) является int, Накопление операций с плавающей точкой в ​​int не только занимает больше времени, чем накапливание в операции с плавающей точкой, но также дает другой результат.

Эквивалентом вашего исходного кода цикла является использование начального значения 0.0fили эквивалентно float{},

(Обратите внимание, что std::accumulate очень похоже в этом отношении.)

Другие вопросы по тегам