C++11 гипотеза медленнее, чем стандартная функция и #define
Я провел тесты на своем процессоре E5 -1620 v3 с использованием VS2013 и проверил, что стандартная функция C++11 hypot занимает на 140% больше времени, чем использование функции или функции #define. Я также дал возможность компилятору распараллелить исчисление во втором раунде теста.
В результате я получил:
C++11 hypot: 55 MOPs (мега операций в секунду)
_hypo функция: 81-82 швабры
#определение функции. : 81-83 швабры
Параллельно 10 операций каждый:
C++11 hypot: 152 MOPs
_hypo функция: 268 швабр
#define func.: 240 MOPs
По крайней мере, результаты этих трех функций совершенно одинаковы.
Является ли это проблемой VS или это может произойти и в системе linux+gcc?
Это может произойти и на AMD ryzen?
ОБНОВЛЕННЫЙ:
Я тестировал также в linux со старым медленным процессором AMD:
Распараллеленные функции дали следующие результаты:
Гипотеза C++11: удвоенная скорость
_hypo функция: 30% скорость incrtease
#define функция: 3x скорость (вдвое больше, чем _hypo)
Что я уже пробовал:
Эта новая версия использует & lt;chronos> и работает также в системах linux и AMD:
#include <iostream> #include <math.h> #include <chrono> #ifdef __linux #include <unistd.h> #else #pragma warning(disable:4996) //disable deprecateds #endif using namespace std; typedef unsigned char uchar; /* time_t start,stop;char null_char='\0'; //Use empty timer() to reset start time: void timer(char *title=&null_char,int data_size=1){ stop=clock(); if (*title) printf("%s time = %7lg = %7lg MOPs\n",title,(double) (stop-start)/(double) CLOCKS_PER_SEC, 1e-6*data_size/( (double)(stop-start)/(double)CLOCKS_PER_SEC ) ); start=clock(); } */ auto start_time=chrono::system_clock::now(),stop_time=start_time;char null_char='\0'; void timer(char *title=&null_char,int data_size=1){ stop_time= chrono::system_clock::now();double us=(double) chrono::duration_cast<chrono::microseconds>(stop_time - start_time).count(); if (*title) printf("%s time = %7lgms = %7lg MOPs\n",title,(double) us*1e-3, (double)data_size/us); start_time= chrono::system_clock::now(); } double _hypo(double x,double y) { x*=x;y*=y;return sqrt(x+y);//quicker than other two //return sqrt(x*x+y*y); //x=sqrt(x*x+y*y);return x; } #define _HYPO(x,y) (sqrt((x)*(x)+(y)*(y))) int main() { int N=10000000;double x,y=12.22; timer(); for (int i=0;i<N;i++) { x=(double) i+1; y=hypot(x,y);y=hypot(x,y); y=hypot(x,y);y=hypot(x,y); y=hypot(x,y);y=hypot(x,y); y=hypot(x,y);y=hypot(x,y); y=hypot(x,y);y=hypot(x,y); } timer("hypot ",10*N); for (int i=0;i<N;i++) { x=(double) i+1; y=_hypo(x,y);y=_hypo(x,y); y=_hypo(x,y);y=_hypo(x,y); y=_hypo(x,y);y=_hypo(x,y); y=_hypo(x,y);y=_hypo(x,y); y=_hypo(x,y);y=_hypo(x,y); } timer("_hypo ",10*N); for (int i=0;i<N;i++) { x=(double) i+1; y=_HYPO(x,y);y=_HYPO(x,y); y=_HYPO(x,y);y=_HYPO(x,y); y=_HYPO(x,y);y=_HYPO(x,y); y=_HYPO(x,y);y=_HYPO(x,y); y=_HYPO(x,y);y=_HYPO(x,y); } timer("#define ",10*N); //Following tests gives an opportunity to be optimized by the compiler&linker: for (int i=0;i<N;i++) { x=(double) i+1; y=hypot(x,y)+hypot(0.5*x,y)+hypot(0.4*x,y)+hypot(0.3*x,y)+hypot(0.2*x,y)+ hypot(x,y)+hypot(0.5*x,y)+hypot(0.4*x,y)+hypot(0.3*x,y)+hypot(0.2*x,y); } timer("hypot par ",10*N); for (int i=0;i<N;i++) { x=(double) i+1; y=_hypo(x,y) +_hypo(0.5 *x,y)+_hypo(0.4 *x,y)+_hypo(0.3 *x,y)+_hypo(0.2 *x,y)+ _hypo(x*0.11,y)+_hypo(0.13*x,y)+_hypo(0.41*x,y)+_hypo(0.31*x,y)+_hypo(0.23*x,y); } timer("_hypo par ",10*N); for (int i=0;i<N;i++) { x=(double) i+1; y=_HYPO(x,y) +_HYPO(0.5 *x,y)+_HYPO(0.4 *x,y)+_HYPO(0.3 *x,y)+_HYPO(0.2 *x,y)+ _HYPO(x*0.11,y)+_HYPO(0.13*x,y)+_HYPO(0.41*x,y)+_HYPO(0.31*x,y)+_HYPO(0.23*x,y); } timer("_HYPO par ",10*N); //Check for errors: x=1.12345;y=y+=.77777732; if ((hypot(x,y)!=_hypo(x,y))||(hypot(x,y)!=_HYPO(x,y))) cout<<"ERROR: "<<hypot(x,y)<<"!="<<_hypo(x,y) <<" or "<<hypot(x,y)<<"!="<<_HYPO(x,y)<<endl; else cout<<"hypot(x,y)==_hypo(x,y)==HYPO(x,y)"<<endl; cout<<"===END==="<<endl;getchar(); }