Мне было интересно как std::inner_product()
выполняет по сравнению с ручным вычислением точечного произведения, поэтому я сделал тест.
std::inner_product()
было В 4 раза быстрее чем ручная реализация. Я нахожу это странным, потому что на самом деле не так много способов его вычислить ?! Я также не вижу никаких регистров SSE / AVX, используемых в точке расчета.
Настройка: VS2013 / MSVC (12?), Процессор Haswell i7 4770, 64-разрядная компиляция, релиз Режим.
Вот код теста C ++:
#include <iostream>
#include <functional>
#include <numeric>
#include <cstdint>
int main() {
const int arraySize = 1000;
const int numTests = 500;
unsigned int x, y = 0;
unsigned long long* array1 = new unsigned long long[arraySize];
unsigned long long* array2 = new unsigned long long[arraySize];
//Initialise arrays
for (int i = 0; i < arraySize; i++){
unsigned long long val = __rdtsc();
array1[i] = val;
array2[i] = val;
}
//std::inner_product test
unsigned long long timingBegin1 = __rdtscp(&s);
for (int i = 0; i < numTests; i++){
volatile unsigned long long result = std::inner_product(array1, array1 + arraySize, array2, static_cast<uint64_t>(0));
}
unsigned long long timingEnd1 = __rdtscp(&s);
f, s = 0;
//Manual Dot Product test
unsigned long long timingBegin2 = __rdtscp(&f);
for (int i = 0; i < numTests; i++){
volatile unsigned long long result = 0;
for (int i = 0; i < arraySize; i++){
result += (array1[i] * array2[i]);
}
}
unsigned long long timeEnd2 = __rdtscp(&f);std::cout << "STL: : " << static_cast<double>(finish1 - start1) / numTests << " CPU cycles per dot product" << std::endl;
std::cout << "Manually : " << static_cast<double>(finish2 - start2) / numTests << " CPU cycles per dot product" << std::endl;
Ваш тест плох, и это, вероятно, будет иметь большое значение.
volatile uint64_t result = 0; for (int i = 0; i < arraySize; i++){ result += (array1[i] * array2[i]);
Обратите внимание, как вы постоянно используете volatile
переменная здесь. Это заставляет компилятор записывать временные результаты в память.
В отличие от вашего inner_product
версия:
volatile uint64_t result = std::inner_product(array1, array1 + arraySize, array2, static_cast<uint64_t>(0));
сначала вычисляет внутренний продукт, что позволяет оптимизировать, и только потом присваивает результат volatile
четвертая переменная.