Версия Windows для моего программного обеспечения в 2-3 раза медленнее, чем для Linux.Чтобы отладить это и продемонстрировать проблему, я создал три простых тестовых функции:
- benchDouble () выполняет вычисления двойной точности
- benchCgalSimple () вычисляет пересечение двух линий безвысокоточные числа
- benchCgalGmpq () вычисляет скользящее пересечение двух линий так, что требуются числа GMPQ
Я настроил циклы так, что на моем эталонном компьютере каждая функция принимает ~5 секунд:
i7-6800K CPU @ 3,40 ГГц, Linux x64
Time consumption:
* START [Double precision test]...
* STOP [Double precision test]:5.21951 s
* START [CGAL simple]...
* STOP [CGAL simple]:4.98616 s
* START [CGAL GMPQ]...
* STOP [CGAL GMPQ]:4.93984 s
Factors:
CgalSimple / Double = 0.955293
CgalGmpq / Double = 0.946417
Теперь давайте проверим это под Windows:
i7-6800K CPU @ 3,40 ГГц, Win10в Virtualbox
* START [Double precision test]...
* STOP [Double precision test]:4.82424 s
* START [CGAL simple]...
* STOP [CGAL simple]:9.251 s
* START [CGAL GMPQ]...
* STOP [CGAL GMPQ]:12.723 s
Factors:
CgalSimple / Double = 1.91761
CgalGmpq / Double = 2.63732
... Virtualbox и другой компилятор не оказывают существенного эффекта, поскольку первый тест занимает еще около 5 секунд.Но потребление времени для функций CGAL в 2,6 раза выше.
Xeon E5645 @ 2,4 ГГц, Win10 direct (без виртуальной машины)
Time consumption:
* START [Double precision test]...
* STOP [Double precision test]:10.1158 s
* START [CGAL simple]...
* STOP [CGAL simple]:15.8708 s
* START [CGAL GMPQ]...
* STOP [CGAL GMPQ]:20.1676 s
Factors:
CgalSimple / Double = 1.5689
CgalGmpq / Double = 1.99366
... на старом сервере Xeon результат аналогичен, функции CGAL работают в 2 раза медленнее, чемдвойной тест точности.
Условия компиляции:
Я использовал CGAL-4.13.1.CGAL и эталонная программа были скомпилированы под Win10 с VS2015.Я уже пробовал различные варианты оптимизации.Последний тест был выполнен с помощью команды:
(Редактировать: настройка оптимизации изменена на O2)
/ MP / GS- / TP / GL / W3 / Zc: wchar_t / I "c: \ benchCgal "/ I" c: \ benchCgal \ 3rdParty_64 \ boost_1_68_0 "/I"c:\local\CGAL-4.13.1" /I"c:\local\CGAL-4.13.1\build\include "/Я "c: \ local \ CGAL-4.13.1 \ build \ include \ CGAL" /I"C:\local\CGAL-4.13.1\auxiliary\gmp\include "/ I" C: \ benchCgal \ winBuild2 "/Я "C: \ local \ CGAL-4.13.1 \ lib \ cmake \ CGAL ...... \ include" / Gm- / O2 / Ob2 /Fd"benchCgal.dir\Release\vc140.pdb "/ Zc:inline / fp: точный / D "WIN32" / D "_WINDOWS" / D "NDEBUG" / D "BOOST_ALL_DYN_LINK" / D "CMAKE_INTDIR = \" Release \ "" / D "_MBCS" / errorReport: подсказка / GT / WX-/ Zc: forScope / GR / Gd / Oy / Oi / MD / Fa "Release /" / EHsc / Fo "benchCgal.dir \ Release \" / Ot /Fp"benchCgal.dir\Release\benchCgal.pch "
Тестовая программа:
#include <stdio.h>
#include <iostream>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <math.h>
#include <chrono>
typedef CGAL::Exact_predicates_exact_constructions_kernel K;
typedef K::FT dbl;
typedef K::Line_3 Line_3;
typedef K::Point_3 Point_3;
typedef std::chrono::time_point<std::chrono::high_resolution_clock> TimePoint;
typedef std::chrono::duration<double> Duration;
using namespace std;
double stopWatch(const std::string& s)
{
static bool bRunning(false);
static TimePoint start;
if(bRunning)
{
Duration d(std::chrono::high_resolution_clock::now()-start);
cout<<"* STOP ["<<s<<"]:"<<d.count()<<" s"<<endl<<endl;
bRunning=false;
return d.count();
}
else
{
cout<<"* START ["<<s<<"]..."<<endl;
bRunning=true;
start=std::chrono::high_resolution_clock::now();
return -1;
}
}
double sum(1.0);
void benchDouble()
{
for(double i=0;i<185;i+=1.0)
{
for(double j=0;j<1000;j+=1.0)
{
for(double k=0;k<1000;k+=1.0)
{
sum+=sqrt(i*i+j*j+k*k)*sqrt(i*k+j*k+i*j);
sum+=cos(.00314*k)+sin(.00314*k);
sum/=(i+k+j*j+1);
}
}
}
}
double benchCgalSimple()
{
double sum(0);
for(int i=0;i<3731000;++i)
{
Point_3 p0(0,0,0);
Point_3 p1(2,0,0);
Point_3 p2(1,1,0);
Point_3 p3(1,-1,0);
Line_3 line0(p0,p1);
Line_3 line1(p2,p3);
if(!do_intersect(line0,line1)) continue;
CGAL::Object obj(CGAL::intersection(line0,line1));
Point_3 isp;
bool bOK(CGAL::assign(isp,obj));
if(bOK) sum+=to_double(isp.x()+isp.y()+isp.z());
}
return sum;
}
double benchCgalGmpq()
{
double sum(0);
for(int i=0;i<96198;++i)
{
Point_3 p0(0,0,0);
Point_3 p1(1,DBL_MIN,DBL_MIN);
Point_3 p2(2,DBL_MIN,DBL_MIN);
Point_3 p3(3,0,0);
Line_3 line0(p0,p1);
Line_3 line1(p2,p3);
if(!do_intersect(line0,line1)) continue;
CGAL::Object obj(CGAL::intersection(line0,line1));
Point_3 isp;
bool bOK(CGAL::assign(isp,obj));
if(bOK) sum+=to_double(isp.x().exact()+isp.y().exact()+isp.z().exact());
}
return sum;
}
int main()
{
cout<<"Benchmarks started..."<<endl<<endl;
cout<<"Time consumption: "<<endl;
stopWatch("Double precision test");
benchDouble();
double timeDouble=stopWatch("Double precision test");
stopWatch("CGAL simple");
benchCgalSimple();
double timeCgalSimple=stopWatch("CGAL simple");
stopWatch("CGAL GMPQ");
benchCgalGmpq();
double timeCgalGmpq=stopWatch("CGAL GMPQ");
cout<<"Factors:"<<endl;
cout<<" CgalSimple / Double = "<<timeCgalSimple/timeDouble<<endl;
cout<<" CgalGmpq / Double = "<<timeCgalGmpq/timeDouble<<endl;
}
Примечание: Вышеприведенный тест вычисляет не только абсолютные затраты времени, но и два фактора, которые сравнивают функции CGAL с функцией не-CGAL.Эти факторы составляют около 1,0 в Linux и до 2,6 в Windows.Различные типы ЦП (или в одном случае использование ВМ) влияют на всю программу, и поэтому факторы все еще значимы.
(правка):
Новые контрольные данные
ВОбсуждение ниже эталонного метода обсуждалось потому, что Windows работала на виртуальной машине.Теперь коллега запустил его для меня на своей машине с двойной загрузкой, i7-7700 CPU @ 3,6 ГГц.
WINDOWS:
* START [Double precision test]...
* STOP [Double precision test]:3.13713 s
* START [CGAL simple]...
* STOP [CGAL simple]:7.66628 s (+86 % compared to linux)
* START [CGAL GMPQ]...
* STOP [CGAL GMPQ]:10.6407 s (+78% compared to linux)
Linux:
* START [Double precision test]...
* STOP [Double precision test]:4.41382 s
* START [CGAL simple]...
* STOP [CGAL simple]:4.10052 s
* START [CGAL GMPQ]...
* STOP [CGAL GMPQ]:5.97985 s