2015-08-26 15 views
10

Ich versuche, die Leistung von std::sort (mit std::vector von Strukturen) vs Intel ipp sort zu vergleichen.Std :: Sortierung vs Intel ipp Sortierleistung. Was mache ich falsch?

ich diesen Test Prozessor auf einem Intel Xeon model name : Intel(R) Xeon(R) CPU X5670 @ 2.93GHz

ich einen Vektor der Länge 20000 Elemente am Sortieren und Sortieren von 200 mal leite. Ich habe 2 verschiedene ipp Sortierroutinen viz versucht. ippsSortDescend_64f_I und ippsSortRadixDescend_64f_I. In allen Fällen war ipp Sortierung mindestens 5 bis 10 mal langsamer als std::sort. Ich habe erwartet, dass die ipp Sortierung möglicherweise für kleinere Arrays langsamer ist, aber ansonsten sollte es in der Regel schneller als std::sort sein. Fehle ich hier etwas? Was mache ich falsch?

std::sort ist in allen meinen Testfällen konsistent schneller.

Hier ist mein Programm

#include <array> 
#include <iostream> 
#include <algorithm> 
#include <stdlib.h> 
#include <time.h> 
#include <sys/time.h> 
#include <sys/timeb.h> 

#include <vector> 
#include <chrono> 

#include "ipp.h" 

using namespace std; 

const int SIZE = 2000000; 
const int ITERS = 200; 

//Chrono typedefs 
typedef std::chrono::high_resolution_clock Clock; 
typedef std::chrono::microseconds microseconds; 

//////////////////////////////////// std /////////////////////////////////// 

typedef vector<double> myList; 

void initialize(myList & l, Ipp64f* ptr) 
{ 
    double randomNum; 
    for (int i = 0; i < SIZE; i++) 
    { 
     randomNum = 1.0 * rand()/(RAND_MAX/2) - 1; 
     l.push_back(randomNum); 
     ptr[i] = randomNum; 
    } 
} 


void test_sort() 
{ 
     array<myList, ITERS> list; 
     array<Ipp64f*, ITERS> ippList; 

     // allocate 
     for(int i=0; i<ITERS;i++) 
     { 
       list[i].reserve(SIZE); 
       ippList[i] = ippsMalloc_64f(SIZE); 
     } 

     // initialize 
     for(int i=0;i<ITERS;i++) 
     { 
       initialize(list[i], ippList[i]); 
     } 

     cout << "\n\nTest Case 1: std::sort\n"; 
     cout << "========================\n"; 

     // sort vector 
     Clock::time_point t0 = Clock::now(); 
     for(int i=0; i<ITERS;i++) 
     { 
      std::sort(list[i].begin(), list[i].end()); 
     } 
     Clock::time_point t1 = Clock::now(); 
     microseconds ms = std::chrono::duration_cast<microseconds>(t1 - t0); 
     std::cout << ms.count() << " micros" << std::endl; 

     ////////////////////////////////// IPP //////////////////////////////////////// 

     cout << "\n\nTest Case 2: ipp::sort\n"; 
     cout << "========================\n"; 

     // sort ipp 
     Clock::time_point t2 = Clock::now(); 
     for(int i=0; i<ITERS;i++) 
     { 
       ippsSortAscend_64f_I(ippList[i], SIZE); 
     } 
     Clock::time_point t3 = Clock::now(); 
     microseconds ms1 = std::chrono::duration_cast<microseconds>(t3 - t2); 
     std::cout << ms1.count() << " micros" << std::endl; 

     for(int i=0; i<ITERS;i++) 
     { 
      ippsFree(ippList[i]); 
     } 
} 


/////////////////////////////////////////////////////////////////////////////////////// 

int main() 
{ 
    srand (time(NULL)); 

    cout << "Test for sorting an array of structures.\n" << endl; 
    cout << "Test case: \nSort an array of structs ("<<ITERS<<" iterations) with double of length "<<SIZE<<". \n"; 
     IppStatus status=ippInit(); 
     test_sort(); 
    return 0; 
} 

///////////////////////////////////////////////////////////////////////////// 

Kompilation Befehl lautet:

/share/intel/bin/icc -O2 -I$(IPPROOT)/include sorting.cpp -lrt -L$(IPPROOT)/lib/intel64 -lippi -lipps -lippvm -lippcore -std=c++0x  

Ausgabeprogramm:

Test for sorting an array of structures. 

Test case: 
Sort an array of structs (200 iterations) with double of length 2000000. 


Test Case 1: std::sort 
======================== 
38117024 micros 


Test Case 2: ipp::sort 
======================== 
48917686 micros 
+1

Beachten Sie, dass Sie nicht nur die Sortierung, sondern auch die Randomisierung der Vektoren benchmarken. Ich empfehle Ihnen, nur die tatsächliche Sortierung zu messen, viele Male, während Sie die Zeiten addieren, um eine Gesamtzeit zu erhalten, und dann die Gesamtzeit sowie die durchschnittliche Zeit anzuzeigen. –

+0

werde ich das jetzt versuchen, aber nur für den Test habe ich versucht, indem ich 'randomize' Funktionen entfernt habe, so dass nur die erste Schleife zufälligen Vektor hat, wo andere Iterationen Vektoren sortiert haben. In diesem Fall war auch 'std :: sort' viel schneller als' ipp'. Wie auch immer, Überprüfung durch Hinzufügen von Zeit jetzt. – Alok

+1

@usr: Der Vergleich soll keine negative Zahl oder irgendeine Zahl zurückgeben. Es soll einen Bool zurückgeben. True, wenn das erste Argument vor dem zweiten steht und andernfalls falsch. –

Antwort

1

für genaueres Ergebnis Sie

    zu

    brauchen
  • vergleichen Sortierung von genau die gleichen Verteilungen von Zufallszahlen;
  • Randomize vom Timing entfernen;
  • Verwenden Sie die ippsSort * 32f-Funktionen, um 'float' (nicht 'double') im IPP-Fall zu sortieren.
+0

Ich habe die Änderungen wie Sie vorgeschlagen gemacht. Ich benutze 'ippsSortDescend_64f_I' und ändere alle' floats' in 'double'. Ich sehe immer noch, dass ipp sort im Vergleich zu 'std :: sort' viel langsamer ist. Ich beginne zu glauben, dass 'std :: sort' effizienter ist als' ipp'. – Alok

-1

Ich denke, Sie haben vergessen, ippInit() vor der Messung!

+0

ist es in der Hauptsache gemacht. – Alok

4

ich Ihren Code auf meinem Computer ausgeführt haben zu nennen (Core i7 860).

std::sort 32,763,268 (~33s) 

ippsSortAscend_64f_I 34,217,517 (~34s) 

ippsSortRadixAscend_64f_I 15,319,053 (~15s) 

Dies sind die erwarteten Ergebnisse. std :: sort ist inline und hoch optimiert, während ippsSort_ * Funktionsaufruf-Overhead und viele innere Überprüfungen durch alle ipp-Funktionen hat. Dies sollte die kleine Verlangsamung für die Funktion ippsSortAscend erklären. Radix-Sortierung ist immer noch doppelt so schnell wie erwartet, da es sich nicht um eine vergleichsorientierte Sortierung handelt.